1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
#
# Amalgamation
#
set(SINGLEHEADER_FILES
${CMAKE_CURRENT_BINARY_DIR}/simdjson.cpp
${CMAKE_CURRENT_BINARY_DIR}/simdjson.h
${CMAKE_CURRENT_BINARY_DIR}/amalgamate_demo.cpp
${CMAKE_CURRENT_BINARY_DIR}/README.md
)
set(SINGLEHEADER_REPO_FILES
${CMAKE_CURRENT_SOURCE_DIR}/simdjson.cpp
${CMAKE_CURRENT_SOURCE_DIR}/simdjson.h
${CMAKE_CURRENT_SOURCE_DIR}/amalgamate_demo.cpp
${CMAKE_CURRENT_SOURCE_DIR}/README.md
)
set_source_files_properties(${SINGLEHEADER_FILES} PROPERTIES GENERATED TRUE)
find_package(Python3 COMPONENTS Interpreter)
if (Python3_Interpreter_FOUND AND (NOT WIN32))
add_custom_command(
OUTPUT ${SINGLEHEADER_FILES}
COMMAND ${CMAKE_COMMAND} -E env
AMALGAMATE_SOURCE_PATH=${PROJECT_SOURCE_DIR}/src
AMALGAMATE_INPUT_PATH=${PROJECT_SOURCE_DIR}/include
AMALGAMATE_OUTPUT_PATH=${CMAKE_CURRENT_BINARY_DIR}
${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/amalgamate.py
#
# This is the best way I could find to make amalgamation trigger whenever source files or
# header files change: since the "simdjson" library has to get rebuilt when that happens, we
# take a dependency on the generated library file (even though we're not using it). Depending
# on simdjson-source doesn't do the trick because DEPENDS here can only depend on an
# *artifact*--it won't scan source and include files the way a concrete library or executable
# will.
#
# It sucks that we have to build the actual library to make it happen, but it's better than\
# nothing!
#
DEPENDS amalgamate.py simdjson
)
##
# This is used by "make amalgamate" to update the original source files.
# You can invoke it as cmake --build . --target amalgamate
# We obviously don't do
# this if source and generated files are in the same place--cmake gets mad!
if (NOT (${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}))
add_custom_target(amalgamate)
add_custom_command(TARGET amalgamate
# We don't want CMake to know that it is writing to the source directory. No magic
# file regeneration in the source directory without the user's knowledge.
# OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/simdjson.cpp ${CMAKE_CURRENT_SOURCE_DIR}/simdjson.h ${CMAKE_CURRENT_SOURCE_DIR}/amalgamate_demo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/README.md
COMMAND ${CMAKE_COMMAND} -E copy ${SINGLEHEADER_FILES} ${CMAKE_CURRENT_SOURCE_DIR}
POST_BUILD ${SINGLEHEADER_FILES}
)
endif()
##
# Adding the ability for CMake to modify the source is problematic. In particular, it will
# happily regenerate the source files that are missing, silently. We do not want to do this.
# If they are missing source files, the build should fail. You should not get silent patching
# by CMake. The user can easily regenerate the files, deliberately.
#
# DO NOT DO THIS:
# add_custom_target(amalgamate DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/simdjson.cpp ${CMAKE_CURRENT_SOURCE_DIR}/simdjson.h ${CMAKE_CURRENT_SOURCE_DIR}/amalgamate_demo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/README.md)
##
else()
# We do not have python3, so we use existing amalgamated files instead of generating them ...
# (Do not do this if the source and destination are the same!)
if (NOT (${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}))
add_custom_command(
OUTPUT ${SINGLEHEADER_FILES}
COMMAND ${CMAKE_COMMAND} -E copy
${SINGLEHEADER_REPO_FILES}
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${SINGLEHEADER_REPO_FILES}
)
endif()
endif()
add_custom_target(singleheader_tests)
add_dependencies(all_tests singleheader_tests)
#
# Do not depend on singleheader files directly: depend on this target instead.
# Otherwise the custom command may get triggered multiple times and race with itself!
#
add_custom_target(singleheader-files DEPENDS ${SINGLEHEADER_FILES})
#
# Include this if you intend to #include "simdjson.cpp" in your own .cpp files.
#
add_library(simdjson-singleheader-include-source INTERFACE)
target_include_directories(simdjson-singleheader-include-source INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
add_dependencies(simdjson-singleheader-include-source singleheader-files)
#
# Include this to get "simdjson.cpp" included in your project as one of the sources.
#
add_library(simdjson-singleheader-source INTERFACE)
target_sources(simdjson-singleheader-source INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/simdjson.cpp>)
target_link_libraries(simdjson-singleheader-source INTERFACE simdjson-singleheader-include-source)
#
# We do not want CMake to update the original source files automatically "in passing" as
# part of a test that generates the files anew. This kind of side-effect is bad.
#
# add_dependencies(simdjson-singleheader-source amalgamate) <=== NO NO NO
#
#
include(${PROJECT_SOURCE_DIR}/cmake/add_compile_only_test.cmake)
#
# Test the generated simdjson.cpp/simdjson.h using the generated amalgamate_demo.cpp
#
# Under Windows you should not mix static and dynamic. Pick one. The following test is static.
if(NOT SIMDJSON_LEGACY_VISUAL_STUDIO AND NOT SIMDJSON_WINDOWS_DLL)
add_executable(amalgamate_demo $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/amalgamate_demo.cpp>)
add_library(amalgamate_demo_simdjson $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/simdjson.cpp>)
target_link_libraries(amalgamate_demo amalgamate_demo_simdjson simdjson-internal-flags)
target_include_directories(amalgamate_demo_simdjson PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
target_include_directories(amalgamate_demo PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
add_test(amalgamate_demo amalgamate_demo ${EXAMPLE_JSON} ${EXAMPLE_NDJSON})
set_property(TEST amalgamate_demo APPEND PROPERTY LABELS per_implementation singleheader)
add_dependencies(singleheader_tests amalgamate_demo)
MESSAGE( STATUS "Including amalgamate_demo test. ${SIMDJSON_WINDOWS_DLL}" )
else()
MESSAGE( STATUS "You either have an old Visual Studio or you are building a DLL, amalgamate_demo test disabled." )
endif()
# Under Windows you should not mix static and dynamic. Pick one. The following test is static.
if(NOT SIMDJSON_LEGACY_VISUAL_STUDIO AND NOT SIMDJSON_WINDOWS_DLL)
add_library(simdjson-singleheader STATIC "")
target_link_libraries(simdjson-singleheader simdjson-singleheader-source simdjson-internal-flags)
add_compile_only_test(simdjson-singleheader)
set_property(TEST simdjson-singleheader APPEND PROPERTY LABELS per_implementation singleheader)
add_dependencies(singleheader_tests simdjson-singleheader)
MESSAGE( STATUS "Including simdjson-singleheader test." )
else()
MESSAGE( STATUS "You either have an old Visual Studio or you are building a DLL, simdjson-singleheader test disabled." )
endif()
#
# Test the existing simdjson.cpp/simdjson.h using the existing amalgamate_demo.cpp, using
# the files from the repository.
#
# By design, this will fail if the original files are missing (it should).
#
if (NOT (${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}))
add_library(simdjson-singleheader-include-source-direct-from-repository INTERFACE)
target_include_directories(simdjson-singleheader-include-source-direct-from-repository INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
add_library(simdjson-singleheader-source-direct-from-repository INTERFACE)
target_sources(simdjson-singleheader-source-direct-from-repository INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(simdjson-singleheader-source-direct-from-repository INTERFACE simdjson-singleheader-include-source-direct-from-repository)
# If you want to use simdjson as a DLL under Windows, it makes little sense to run the following static test. Furthermore
# when a DLL was built, we pass SIMDJSON_USING_WINDOWS_DYNAMIC_LIBRARY=1 within the simdjson-flags so that static compilation
# breaks. Simply put: under Windows you should not mix static and dynamic. Pick one.
if(NOT SIMDJSON_LEGACY_VISUAL_STUDIO AND NOT SIMDJSON_WINDOWS_DLL)
add_executable(amalgamate_demo_direct_from_repository ${CMAKE_CURRENT_SOURCE_DIR}/amalgamate_demo.cpp)
add_library(amalgamate_demo_direct_from_repository_simdjson ${CMAKE_CURRENT_SOURCE_DIR}/simdjson.cpp)
target_link_libraries(amalgamate_demo_direct_from_repository amalgamate_demo_direct_from_repository_simdjson simdjson-singleheader-include-source-direct-from-repository simdjson-internal-flags)
add_test(amalgamate_demo_direct_from_repository amalgamate_demo_direct_from_repository ${EXAMPLE_JSON} ${EXAMPLE_NDJSON})
set_property(TEST amalgamate_demo_direct_from_repository APPEND PROPERTY LABELS per_implementation singleheader)
add_dependencies(singleheader_tests amalgamate_demo_direct_from_repository)
MESSAGE( STATUS "Including amalgamate_demo_direct_from_repository test." )
else()
MESSAGE( STATUS "You either have an old Visual Studio or you are building a DLL, amalgamate_demo test disabled." )
endif()
endif()
|