diff --git a/CMakeLists.txt b/CMakeLists.txt index e1837566..48ad9975 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,7 @@ if (SNITCH_CREATE_LIBRARY) add_library(snitch ${PROJECT_SOURCE_DIR}/include/snitch/snitch.hpp ${PROJECT_SOURCE_DIR}/include/snitch/snitch_teamcity.hpp + ${PROJECT_BINARY_DIR}/snitch/snitch_config.hpp ${PROJECT_SOURCE_DIR}/src/snitch.cpp) add_library(snitch::snitch ALIAS snitch) @@ -74,27 +75,28 @@ if (SNITCH_CREATE_LIBRARY) endif() if(SNITCH_CREATE_HEADER_ONLY) - # Build as a header-only library. - file(READ ${PROJECT_BINARY_DIR}/snitch/snitch_config.hpp SNITCH_FILE_CONFIG) - file(READ ${PROJECT_SOURCE_DIR}/include/snitch/snitch.hpp SNITCH_FILE_HEADER) - file(READ ${PROJECT_SOURCE_DIR}/src/snitch.cpp SNITCH_FILE_SOURCE) + find_package(Python3) - set(SNITCH_ALL_CONTENT "${SNITCH_FILE_CONFIG}\n${SNITCH_FILE_HEADER}\n#if defined(SNITCH_IMPLEMENTATION)\n${SNITCH_FILE_SOURCE}\n#endif") - - # Remove includes to snitch.hpp; it's all one header now - string(REPLACE "#include \"snitch/snitch.hpp\"\n" "" SNITCH_ALL_CONTENT "${SNITCH_ALL_CONTENT}") - string(REPLACE "#include \"snitch/snitch_config.hpp\"\n" "" SNITCH_ALL_CONTENT "${SNITCH_ALL_CONTENT}") + # Build as a header-only library. + add_custom_command( + COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/make_snitch_all.py" "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}" + VERBATIM + OUTPUT ${PROJECT_BINARY_DIR}/snitch/snitch_all.hpp + DEPENDS + ${PROJECT_SOURCE_DIR}/include/snitch/snitch.hpp + ${PROJECT_BINARY_DIR}/snitch/snitch_config.hpp + ${PROJECT_SOURCE_DIR}/src/snitch.cpp) - file(GENERATE OUTPUT ${PROJECT_BINARY_DIR}/snitch/snitch_all.hpp CONTENT "${SNITCH_ALL_CONTENT}") + add_custom_target(snitch-header-only-impl ALL DEPENDS ${PROJECT_BINARY_DIR}/snitch/snitch_all.hpp) add_library(snitch-header-only INTERFACE) add_library(snitch::snitch-header-only ALIAS snitch-header-only) + add_dependencies(snitch-header-only snitch-header-only-impl) set_target_properties(snitch-header-only PROPERTIES EXPORT_NAME snitch::snitch-header-only) target_sources(snitch-header-only INTERFACE $ $) - set_source_files_properties(${PROJECT_BINARY_DIR}/snitch/snitch_all.hpp PROPERTIES GENERATED TRUE) target_include_directories(snitch-header-only INTERFACE $ $) diff --git a/make_snitch_all.py b/make_snitch_all.py new file mode 100644 index 00000000..4e115437 --- /dev/null +++ b/make_snitch_all.py @@ -0,0 +1,44 @@ +import sys +import os + +if len(sys.argv) != 3: + print('error: expected two command line arguments: ') + exit() + +root_dir = sys.argv[1] +binary_dir = sys.argv[2] + +output_dir = os.path.join(binary_dir, 'snitch') +output_filename = 'snitch_all.hpp' + +# Files to concatenate, in order +input_filenames = [os.path.join(binary_dir, 'snitch/snitch_config.hpp'), + os.path.join(root_dir, 'include/snitch/snitch.hpp'), + os.path.join(root_dir, 'src/snitch.cpp')] + +# Make sure the output directory exists; should always be true since we read +# 'snitch_config.hpp' from there, but in case this changes in the future: +os.makedirs(output_dir, exist_ok=True) + +with open(os.path.join(output_dir, output_filename), 'w') as output_file: + file_count = 0 + for input_filename in input_filenames: + # Add guard for implementation files + if '.cpp' in input_filename: + output_file.write('#if defined(SNITCH_IMPLEMENTATION)\n') + + # Write whole file + with open(input_filename, 'r') as input_file: + for line in input_file.readlines(): + # Remove includes to snitch/*.hpp; it's all one header now + if '#include "snitch' in line: + continue + output_file.write(line) + + # Close guard for implementation files + if '.cpp' in input_filename: + output_file.write('#endif\n') + + file_count += 1 + if file_count != len(input_filenames): + output_file.write('\n')