diff --git a/CMakeModules/Functions.cmake b/CMakeModules/Functions.cmake index e3d7f8c9ec..c854723ca2 100644 --- a/CMakeModules/Functions.cmake +++ b/CMakeModules/Functions.cmake @@ -25,17 +25,28 @@ # Function make_lexer # is a standard way to invoke TokenList2DsnLexer.cmake. # Extra arguments are treated as source files which depend on the generated -# outHeaderFile +# files. Some detail here on the indirection: +# - Parallel builds all depend on the same files, and CMake will generate the same file multiple times in the same location. +# This can be problematic if the files are generated at the same time and overwrite each other. +# - To fix this, we create a custom target (outputTarget) that the parallel builds depend on. +# - This almost works except that our targets that depend on targets don't get the file-level dependencies +# - So we have one additional layer of indirection to create an intermediate target with file dependencies +# AND build dependencies. This creates the needed rebuild for appropriate source object changes. +function( make_lexer outputTarget inputFile outHeaderFile outCppFile enum ) + get_filename_component( outHeaderFileBase ${outHeaderFile} NAME ) + get_filename_component( outCppFileBase ${outCppFile} NAME ) + set( intermediateHeader "${CMAKE_CURRENT_BINARY_DIR}/${outHeaderFileBase}.1" ) + set( intermediateCpp "${CMAKE_CURRENT_BINARY_DIR}/${outCppFileBase}.1" ) + set( intermediateTarget "${outHeaderFileBase}.target" ) -function( make_lexer inputFile outHeaderFile outCppFile enum ) add_custom_command( - OUTPUT ${outHeaderFile} - ${outCppFile} + OUTPUT ${intermediateHeader} + ${intermediateCpp} COMMAND ${CMAKE_COMMAND} -Denum=${enum} -DinputFile=${inputFile} - -DoutHeaderFile=${outHeaderFile} - -DoutCppFile=${outCppFile} + -DoutHeaderFile=${intermediateHeader} + -DoutCppFile=${intermediateCpp} -P ${CMAKE_MODULE_PATH}/TokenList2DsnLexer.cmake DEPENDS ${inputFile} ${CMAKE_MODULE_PATH}/TokenList2DsnLexer.cmake @@ -45,11 +56,31 @@ function( make_lexer inputFile outHeaderFile outCppFile enum ) ${inputFile}" ) + add_custom_target( + ${intermediateTarget} + DEPENDS ${intermediateHeader} + ${intermediateCpp} + ) + + add_custom_command( + OUTPUT ${outHeaderFile} + ${outCppFile} + DEPENDS ${intermediateTarget} ${intermediateHeader} ${intermediateCpp} + COMMAND ${CMAKE_COMMAND} -E copy ${intermediateHeader} ${outHeaderFile} + COMMAND ${CMAKE_COMMAND} -E copy ${intermediateCpp} ${outCppFile} + ) + + add_custom_target( + ${outputTarget} ALL + DEPENDS ${outHeaderFile} + ${outCppFile} + ) + # extra_args, if any, are treated as source files (typically headers) which # are known to depend on the generated outHeader. foreach( extra_arg ${ARGN} ) set_source_files_properties( ${extra_arg} - PROPERTIES OBJECT_DEPENDS ${outHeaderFile} + PROPERTIES OBJECT_DEPENDS ${outputTarget} ) endforeach() diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 5b47172ba1..45337092c2 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -515,6 +515,7 @@ target_link_libraries( pcbcommon PUBLIC # auto-generate netlist_lexer.h and netlist_keywords.cpp make_lexer( + netlist_lexer_source_files ${CMAKE_CURRENT_SOURCE_DIR}/netlist.keywords ${PROJECT_SOURCE_DIR}/include/netlist_lexer.h ${CMAKE_CURRENT_SOURCE_DIR}/netlist_keywords.cpp @@ -524,18 +525,12 @@ make_lexer( ${CMAKE_PROJECT_SOURCE_DIR}/pcbnew/netlist_reader.h ) -add_custom_target( - netlist_lexer_source_files ALL - DEPENDS - ${PROJECT_SOURCE_DIR}/include/netlist_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/netlist_keywords.cpp - ) - add_dependencies( common netlist_lexer_source_files ) add_dependencies( pcbcommon netlist_lexer_source_files ) # auto-generate pcb_plot_params_lexer.h and pcb_plot_params_keywords.cpp make_lexer( + pcb_plot_lexer_source_files ${CMAKE_CURRENT_SOURCE_DIR}/pcb_plot_params.keywords ${PROJECT_SOURCE_DIR}/include/pcb_plot_params_lexer.h ${CMAKE_CURRENT_SOURCE_DIR}/pcb_plot_params_keywords.cpp @@ -545,17 +540,11 @@ make_lexer( ${PROJECT_SOURCE_DIR}/pcbnew/pcb_plot_params.h ) -add_custom_target( - pcb_plot_lexer_source_files ALL - DEPENDS - ${PROJECT_SOURCE_DIR}/include/pcb_plot_params_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_plot_params_keywords.cpp - ) - add_dependencies( pcbcommon pcb_plot_lexer_source_files ) # auto-generate pcbnew_sexpr.h and pcbnew_sexpr.cpp make_lexer( + pcb_lexer_source_files ${CMAKE_CURRENT_SOURCE_DIR}/pcb.keywords ${PROJECT_SOURCE_DIR}/include/pcb_lexer.h ${CMAKE_CURRENT_SOURCE_DIR}/pcb_keywords.cpp @@ -565,49 +554,30 @@ make_lexer( ${PROJECT_SOURCE_DIR}/pcbnew/pcb_parser.h ) -add_custom_target( - pcb_lexer_source_files ALL - DEPENDS - ${PROJECT_SOURCE_DIR}/include/pcb_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_keywords.cpp - ) - add_dependencies( pcbcommon pcb_lexer_source_files ) # auto-generate s-expression library table code. make_lexer( + lib_table_lexer_source_files ${CMAKE_CURRENT_SOURCE_DIR}/lib_table.keywords ${PROJECT_SOURCE_DIR}/include/lib_table_lexer.h ${CMAKE_CURRENT_SOURCE_DIR}/lib_table_keywords.cpp LIB_TABLE_T ) -add_custom_target( - lib_table_lexer_source_files ALL - DEPENDS - ${PROJECT_SOURCE_DIR}/include/lib_table_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/lib_table_keywords.cpp - ) - add_dependencies( common lib_table_lexer_source_files ) add_dependencies( pcbcommon lib_table_lexer_source_files ) # auto-generate page layout reader s-expression page_layout_reader_lexer.h # and title_block_reader_keywords.cpp. make_lexer( + page_layout_lexer_source_files ${CMAKE_CURRENT_SOURCE_DIR}/page_layout/page_layout_reader.keywords ${PROJECT_SOURCE_DIR}/include/page_layout_reader_lexer.h ${CMAKE_CURRENT_SOURCE_DIR}/page_layout/page_layout_reader_keywords.cpp TB_READER_T ) -add_custom_target( - page_layout_lexer_source_files ALL - DEPENDS - ${PROJECT_SOURCE_DIR}/include/page_layout_reader_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/page_layout/page_layout_reader_keywords.cpp - ) - add_dependencies( common page_layout_lexer_source_files ) # This one gets made only when testing. diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 244d25bfd5..425686f82f 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -449,22 +449,17 @@ endif() # auto-generate cmp_library_lexer.h and cmp_library_keywords.cpp for the component # library format. make_lexer( + cmp_library_lexer_source_files ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library.keywords ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_lexer.h ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_keywords.cpp TLIB_T ) -add_custom_target( - cmp_library_lexer_source_files ALL - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_keywords.cpp - ) - add_dependencies( eeschema_kiface cmp_library_lexer_source_files ) make_lexer( + field_template_lexer_source_files ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames.keywords ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_lexer.h ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_keywords.cpp @@ -474,16 +469,10 @@ make_lexer( template_fieldnames.h ) -add_custom_target( - field_template_lexer_source_files ALL - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_keywords.cpp - ) - add_dependencies( eeschema_kiface field_template_lexer_source_files ) make_lexer( + dialog_bom_cfg_lexer_source_files ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg.keywords ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_lexer.h ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_keywords.cpp @@ -493,13 +482,6 @@ make_lexer( dialogs/dialog_bom_cfg.h ) -add_custom_target( - dialog_bom_cfg_lexer_source_files ALL - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_keywords.cpp - ) - add_dependencies( eeschema_kiface dialog_bom_cfg_lexer_source_files ) add_subdirectory( plugins ) diff --git a/pcb_calculator/CMakeLists.txt b/pcb_calculator/CMakeLists.txt index e040451298..0cfeb538e4 100644 --- a/pcb_calculator/CMakeLists.txt +++ b/pcb_calculator/CMakeLists.txt @@ -145,6 +145,7 @@ endif() # auto-generate pcb_calculator_datafile.h and pcb_calculator_datafile_keywords.cpp # for the storage data file format. make_lexer( + pcb_calculator_lexer_source_files ${CMAKE_CURRENT_SOURCE_DIR}/pcb_calculator_datafile.keywords ${CMAKE_CURRENT_SOURCE_DIR}/pcb_calculator_datafile_lexer.h ${CMAKE_CURRENT_SOURCE_DIR}/pcb_calculator_datafile_keywords.cpp @@ -154,13 +155,6 @@ make_lexer( datafile_read_write.h ) -add_custom_target( - pcb_calculator_lexer_source_files ALL - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_calculator_datafile_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_calculator_datafile_keywords.cpp -) - # # Conversion of .html doc source files to .h files included in cpp sources # diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 1d3cc5cf54..0662b75d57 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -378,6 +378,7 @@ set( PCBNEW_SCRIPTING_PYTHON_HELPERS # auto-generate specctra_lexer.h and specctra_keywords.cpp make_lexer( + specctra_lexer_source_files ${CMAKE_CURRENT_SOURCE_DIR}/specctra_import_export/specctra.keywords ${CMAKE_CURRENT_SOURCE_DIR}/specctra_import_export/specctra_lexer.h ${CMAKE_CURRENT_SOURCE_DIR}/specctra_import_export/specctra_keywords.cpp @@ -387,14 +388,6 @@ make_lexer( specctra_import_export/specctra.h ) -add_custom_target( - specctra_lexer_source_files ALL - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/specctra_import_export/specctra_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/specctra_import_export/specctra_keywords.cpp - ) - - if( COMPILER_SUPPORTS_WSHADOW ) # .cpp files are compiled with extra ${WSHADOW_FLAGS}, but not .cxx files set_source_files_properties(