From 1103f86cd96238903ae1c01c8af4bb672079d5c0 Mon Sep 17 00:00:00 2001 From: Ryan Ofsky Date: Sun, 26 Jan 2025 12:01:08 -0500 Subject: [PATCH 1/2] cmake: Define and use MP_INCLUDE_DIR variable This is needed to refer to the include directory when the cmake project is not a top-level project (when it is included with add_subdirectory) because ${CMAKE_SOURCE_DIR}/include will no longer refer to the right location. This is also nice because the variable can be used in the target_capnp_sources function and simplify calls to that function. --- CMakeLists.txt | 2 ++ cmake/TargetCapnpSources.cmake | 4 ++-- example/CMakeLists.txt | 12 +++--------- test/CMakeLists.txt | 4 +--- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4fc1c748..cacff00d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,8 @@ include("cmake/compat_config.cmake") include("cmake/pthread_checks.cmake") include(GNUInstallDirs) +set(MP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") + # Generated C++ preprocessor defines configure_file(include/mp/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/mp/config.h") diff --git a/cmake/TargetCapnpSources.cmake b/cmake/TargetCapnpSources.cmake index 47da24bc..cdc86c69 100644 --- a/cmake/TargetCapnpSources.cmake +++ b/cmake/TargetCapnpSources.cmake @@ -68,7 +68,7 @@ function(target_capnp_sources target include_prefix) foreach(capnp_file IN LISTS TCS_UNPARSED_ARGUMENTS) add_custom_command( OUTPUT ${capnp_file}.c++ ${capnp_file}.h ${capnp_file}.proxy-client.c++ ${capnp_file}.proxy-types.h ${capnp_file}.proxy-server.c++ ${capnp_file}.proxy-types.c++ ${capnp_file}.proxy.h - COMMAND Libmultiprocess::mpgen ${CMAKE_CURRENT_SOURCE_DIR} ${include_prefix} ${CMAKE_CURRENT_SOURCE_DIR}/${capnp_file} ${TCS_IMPORT_PATHS} + COMMAND Libmultiprocess::mpgen ${CMAKE_CURRENT_SOURCE_DIR} ${include_prefix} ${CMAKE_CURRENT_SOURCE_DIR}/${capnp_file} ${TCS_IMPORT_PATHS} ${MP_INCLUDE_DIR} DEPENDS ${capnp_file} VERBATIM ) @@ -89,7 +89,7 @@ function(target_capnp_sources target include_prefix) if(relative_path) string(APPEND build_include_prefix "/" "${relative_path}") endif() - target_include_directories(${target} PUBLIC $) + target_include_directories(${target} PUBLIC $ ${MP_INCLUDE_DIR}) if(TARGET Libmultiprocess::multiprocess) target_link_libraries(${target} PRIVATE Libmultiprocess::multiprocess) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index a776322f..d6adc92e 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -7,27 +7,21 @@ include(${PROJECT_SOURCE_DIR}/cmake/TargetCapnpSources.cmake) add_executable(mpcalculator calculator.cpp ) -target_capnp_sources(mpcalculator ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp - IMPORT_PATHS ${CMAKE_SOURCE_DIR}/include -) +target_capnp_sources(mpcalculator ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp) target_include_directories(mpcalculator PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(mpcalculator PRIVATE Threads::Threads) add_executable(mpprinter printer.cpp ) -target_capnp_sources(mpprinter ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp - IMPORT_PATHS ${CMAKE_SOURCE_DIR}/include -) +target_capnp_sources(mpprinter ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp) target_include_directories(mpprinter PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(mpprinter PRIVATE Threads::Threads) add_executable(mpexample example.cpp ) -target_capnp_sources(mpexample ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp - IMPORT_PATHS ${CMAKE_SOURCE_DIR}/include -) +target_capnp_sources(mpexample ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp) target_include_directories(mpexample PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(mpexample PRIVATE Threads::Threads) target_link_libraries(mpexample PRIVATE stdc++fs) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b6ae925b..8ef66a76 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,9 +24,7 @@ if(BUILD_TESTING AND TARGET CapnProto::kj-test) mp/test/test.cpp ) include(${PROJECT_SOURCE_DIR}/cmake/TargetCapnpSources.cmake) - target_capnp_sources(mptest ${CMAKE_CURRENT_SOURCE_DIR} mp/test/foo.capnp - IMPORT_PATHS ${CMAKE_SOURCE_DIR}/include - ) + target_capnp_sources(mptest ${CMAKE_CURRENT_SOURCE_DIR} mp/test/foo.capnp) target_include_directories(mptest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(mptest PRIVATE CapnProto::kj-test) target_link_libraries(mptest PRIVATE Threads::Threads) From 6adbb1d6ebe3ca00063ae5950e4393a0ccba67b2 Mon Sep 17 00:00:00 2001 From: Ryan Ofsky Date: Sun, 26 Jan 2025 12:07:49 -0500 Subject: [PATCH 2/2] cmake: Support being included with add_subdirectory Make changes needed to make the cmake project work well when it is not the top level project and has been included with add_subdirectory: - Avoid defining "tests" and "check" targets when project is not at the top level to avoid clashes. Add new "mptests" and "mpcheck" alternatives instead. - Rename "example" target to "mpexamples" - Rename "util" target to "mputil" - Export MP_INCLUDE_DIR variable to parent scope so target_capnp_sources() function can work well there. - Replace uses of CMAKE_SOURCE_DIR with CMAKE_CURRENT_SOURCE_DIR - Reset INCLUDE_DIRECTORIES property so include_directories calls in the parent project do not affect this project. This was causing errors because the bitcoin core build was adding global include directories and causing its init.h file to take precedence over local one. --- CMakeLists.txt | 25 +++++++++++++++++++------ example/CMakeLists.txt | 2 +- test/CMakeLists.txt | 13 ++++++++++--- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cacff00d..72f686aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,20 @@ include("cmake/compat_config.cmake") include("cmake/pthread_checks.cmake") include(GNUInstallDirs) +# Set convenience variables for subdirectories. set(MP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(MP_STANDALONE TRUE) +else() + # Set MP_INCLUDE_DIR for parent directories too, so target_capnp_sources calls + # in parent directories can use it and not need to specify include directories + # manually or see capnproto error "error: Import failed: /mp/proxy.capnp" + set(MP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE) + set(MP_STANDALONE FALSE) +endif() + +# Prevent include directories from parent project from leaking into this one. +set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES "") # Generated C++ preprocessor defines configure_file(include/mp/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/mp/config.h") @@ -35,10 +48,10 @@ configure_file(include/mp/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/mp/co capnp_generate_cpp(MP_PROXY_SRCS MP_PROXY_HDRS include/mp/proxy.capnp) # util library -add_library(util OBJECT src/mp/util.cpp) -target_include_directories(util PRIVATE - $ - $ +add_library(mputil OBJECT src/mp/util.cpp) +target_include_directories(mputil PRIVATE + $ + $ ${CAPNP_INCLUDE_DIRECTORY}) # libmultiprocess.a runtime library @@ -52,7 +65,7 @@ add_library(multiprocess STATIC ${MP_PROXY_SRCS} ${MP_PUBLIC_HEADERS} src/mp/proxy.cpp - $) + $) add_library(Libmultiprocess::multiprocess ALIAS multiprocess) target_include_directories(multiprocess PUBLIC $ @@ -70,7 +83,7 @@ install(TARGETS multiprocess EXPORT LibTargets PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mp COMPONENT lib) # mpgen code generator -add_executable(mpgen src/mp/gen.cpp $) +add_executable(mpgen src/mp/gen.cpp $) add_executable(Libmultiprocess::mpgen ALIAS mpgen) target_include_directories(mpgen PRIVATE $) target_include_directories(mpgen PUBLIC $ $) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index d6adc92e..333462b8 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -26,4 +26,4 @@ target_include_directories(mpexample PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(mpexample PRIVATE Threads::Threads) target_link_libraries(mpexample PRIVATE stdc++fs) -add_custom_target(example DEPENDS mpexample mpcalculator mpprinter) +add_custom_target(mpexamples DEPENDS mpexample mpcalculator mpprinter) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8ef66a76..129cb563 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,8 +11,15 @@ include(CTest) # that were previously built, without building anything itself. Define "make # tests" here as a custom target to build all available tests and "make check" # as a custom target to build and run them. -add_custom_target(tests) -add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS tests) +add_custom_target(mptests) +add_custom_target(mpcheck COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS mptests) + +# Only add more convenient tests and check targets if project is being built +# standlone, to prevent clashes with external projects. +if (MP_STANDALONE) + add_custom_target(tests DEPENDS mptests) + add_custom_target(check DEPENDS mpcheck) +endif() if(BUILD_TESTING AND TARGET CapnProto::kj-test) set_property(SOURCE ${MP_PROXY_HDRS} PROPERTY GENERATED 1) @@ -29,6 +36,6 @@ if(BUILD_TESTING AND TARGET CapnProto::kj-test) target_link_libraries(mptest PRIVATE CapnProto::kj-test) target_link_libraries(mptest PRIVATE Threads::Threads) - add_dependencies(tests mptest) + add_dependencies(mptests mptest) add_test(NAME mptest COMMAND mptest) endif()