diff --git a/CMakeLists.txt b/CMakeLists.txt index 04f68c8..e0e69af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ add_library(multiprocess STATIC ${MP_PUBLIC_HEADERS} src/mp/proxy.cpp $) +add_library(Libmultiprocess::multiprocess ALIAS multiprocess) target_include_directories(multiprocess PUBLIC $ $ @@ -102,6 +103,7 @@ add_custom_target(install-lib add_dependencies(install-lib multiprocess) add_executable(mpgen src/mp/gen.cpp $) +add_executable(Libmultiprocess::mpgen ALIAS mpgen) target_include_directories(mpgen PRIVATE $) target_include_directories(mpgen PUBLIC $ $) target_link_libraries(mpgen PRIVATE CapnProto::capnp) diff --git a/cmake/LibmultiprocessMacros.cmake b/cmake/LibmultiprocessMacros.cmake new file mode 100644 index 0000000..0cda6c8 --- /dev/null +++ b/cmake/LibmultiprocessMacros.cmake @@ -0,0 +1,94 @@ +# Copyright (c) 2024-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +#[=[ + +target_capnp_sources +-------------------- + +This function adds build steps to generate C++ files from Cap'n Proto files +and build them as part of a specified target. + +Arguments: + + target: The name of the CMake target (e.g., a library or executable) to + which the generated source files will be added. This target must already + be defined elsewhere in the CMake scripts. + + include_prefix: Absolute path indicating what portion of capnp source paths + should be used in relative #include statements in the generated C++ + files. For example, if the .capnp path is /home/src/lib/schema.capnp + and include_prefix is /home/src, generated includes look like: + + #include + + And if include_prefix is /home/src/lib, generated includes look like: + + #include + + The specified include_prefix should be ${CMAKE_SOURCE_DIR} or a + subdirectory of it to include files relative to the project root. It can + be ${CMAKE_CURRENT_SOURCE_DIR} to include files relative to the current + source directory. + +Additional Unnamed Arguments: + + After `target` and `include_prefix`, all unnamed arguments are treated as + paths to `.capnp` schema files. These should be paths relative to + ${CMAKE_CURRENT_SOURCE_DIR}. + +Optional Keyword Arguments: + + IMPORT_PATHS: Specifies additional directories to search for imported + `.capnp` files. + +Example: + # Assuming `my_library` is a target and `lib/` contains `.capnp` schema + # files with imports from `include/`. + target_capnp_sources(my_library "${CMAKE_SOURCE_DIR}" + lib/schema1.capnp lib/schema2.capnp + IMPORT_PATHS ${CMAKE_SOURCE_DIR}/include) + +#]=] + +function(target_capnp_sources target include_prefix) + cmake_parse_arguments(PARSE_ARGV 2 + "TCS" # prefix + "" # options + "" # one_value_keywords + "IMPORT_PATHS" # multi_value_keywords + ) + + if(NOT TARGET Libmultiprocess::mpgen) + message(FATAL_ERROR "Target 'Libmultiprocess::mpgen' does not exist.") + endif() + + 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} + DEPENDS ${capnp_file} + VERBATIM + ) + target_sources(${target} PRIVATE + ${CMAKE_CURRENT_BINARY_DIR}/${capnp_file}.c++ + ${CMAKE_CURRENT_BINARY_DIR}/${capnp_file}.proxy-client.c++ + ${CMAKE_CURRENT_BINARY_DIR}/${capnp_file}.proxy-server.c++ + ${CMAKE_CURRENT_BINARY_DIR}/${capnp_file}.proxy-types.c++ + ) + endforeach() + + # Translate include_prefix from a source path to a binary path and add it as a + # target include directory. + set(build_include_prefix ${CMAKE_BINARY_DIR}) + file(RELATIVE_PATH relative_path ${CMAKE_SOURCE_DIR} ${include_prefix}) + if(relative_path) + string(APPEND build_include_prefix "/" "${relative_path}") + endif() + target_include_directories(${target} PUBLIC $) + + if(TARGET Libmultiprocess::multiprocess) + target_link_libraries(${target} PRIVATE Libmultiprocess::multiprocess) + endif() +endfunction() diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 81a2fa8..f0f30bc 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -2,154 +2,34 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -add_custom_command( - OUTPUT - init.capnp.h - init.capnp.c++ - init.capnp.proxy.h - init.capnp.proxy-server.c++ - init.capnp.proxy-client.c++ - init.capnp.proxy-types.c++ - init.capnp.proxy-types.h - COMMAND mpgen "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/init.capnp" "${CMAKE_SOURCE_DIR}/include" "${capnp_PREFIX}/include" - DEPENDS init.capnp mpgen -) - -add_custom_command( - OUTPUT - calculator.capnp.h - calculator.capnp.c++ - calculator.capnp.proxy.h - calculator.capnp.proxy-server.c++ - calculator.capnp.proxy-client.c++ - calculator.capnp.proxy-types.c++ - calculator.capnp.proxy-types.h - COMMAND mpgen "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/calculator.capnp" "${CMAKE_SOURCE_DIR}/include" "${capnp_PREFIX}/include" - DEPENDS calculator.capnp mpgen -) +include(${PROJECT_SOURCE_DIR}/cmake/LibmultiprocessMacros.cmake) add_executable(mpcalculator - calculator.capnp.h - calculator.capnp.c++ - calculator.capnp.proxy.h - calculator.capnp.proxy-server.c++ - calculator.capnp.proxy-client.c++ - calculator.capnp.proxy-types.c++ - calculator.capnp.proxy-types.h calculator.cpp - init.capnp.h - init.capnp.c++ - init.capnp.proxy.h - init.capnp.proxy-server.c++ - init.capnp.proxy-client.c++ - init.capnp.proxy-types.c++ - init.capnp.proxy-types.h - printer.capnp.h - printer.capnp.c++ - printer.capnp.proxy.h - printer.capnp.proxy-server.c++ - printer.capnp.proxy-client.c++ - printer.capnp.proxy-types.c++ - printer.capnp.proxy-types.h ) -target_include_directories(mpcalculator PUBLIC - ${CAPNP_INCLUDE_DIRECTORY} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} +target_capnp_sources(mpcalculator ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp + IMPORT_PATHS ${CMAKE_SOURCE_DIR}/include ) -target_link_libraries(mpcalculator PRIVATE CapnProto::capnp) -target_link_libraries(mpcalculator PRIVATE CapnProto::capnp-rpc) -target_link_libraries(mpcalculator PRIVATE CapnProto::kj) -target_link_libraries(mpcalculator PRIVATE CapnProto::kj-async) +target_include_directories(mpcalculator PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(mpcalculator PRIVATE Threads::Threads) -target_link_libraries(mpcalculator PRIVATE multiprocess) - -add_custom_command( - OUTPUT - printer.capnp.h - printer.capnp.c++ - printer.capnp.proxy.h - printer.capnp.proxy-server.c++ - printer.capnp.proxy-client.c++ - printer.capnp.proxy-types.c++ - printer.capnp.proxy-types.h - COMMAND mpgen "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/printer.capnp" "${CMAKE_SOURCE_DIR}/include" "${capnp_PREFIX}/include" - DEPENDS printer.capnp mpgen -) add_executable(mpprinter - calculator.capnp.c++ - calculator.capnp.h - calculator.capnp.proxy-client.c++ - calculator.capnp.proxy-server.c++ - calculator.capnp.proxy-types.c++ - calculator.capnp.proxy-types.h - calculator.capnp.proxy.h - init.capnp.h - init.capnp.c++ - init.capnp.proxy.h - init.capnp.proxy-server.c++ - init.capnp.proxy-client.c++ - init.capnp.proxy-types.c++ - init.capnp.proxy-types.h - printer.capnp.h - printer.capnp.c++ - printer.capnp.proxy.h - printer.capnp.proxy-server.c++ - printer.capnp.proxy-client.c++ - printer.capnp.proxy-types.c++ - printer.capnp.proxy-types.h printer.cpp ) -target_include_directories(mpprinter PUBLIC - ${CAPNP_INCLUDE_DIRECTORY} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} +target_capnp_sources(mpprinter ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp + IMPORT_PATHS ${CMAKE_SOURCE_DIR}/include ) -target_link_libraries(mpprinter PRIVATE CapnProto::capnp) -target_link_libraries(mpprinter PRIVATE CapnProto::capnp-rpc) -target_link_libraries(mpprinter PRIVATE CapnProto::kj) -target_link_libraries(mpprinter PRIVATE CapnProto::kj-async) +target_include_directories(mpprinter PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(mpprinter PRIVATE Threads::Threads) -target_link_libraries(mpprinter PRIVATE multiprocess) add_executable(mpexample - calculator.capnp.c++ - calculator.capnp.h - calculator.capnp.proxy-client.c++ - calculator.capnp.proxy-server.c++ - calculator.capnp.proxy-types.c++ - calculator.capnp.proxy-types.h - calculator.capnp.proxy.h - init.capnp.c++ - init.capnp.h - init.capnp.proxy-client.c++ - init.capnp.proxy-server.c++ - init.capnp.proxy-types.c++ - init.capnp.proxy-types.h - init.capnp.proxy.h - printer.capnp.h - printer.capnp.c++ - printer.capnp.proxy.h - printer.capnp.proxy-server.c++ - printer.capnp.proxy-client.c++ - printer.capnp.proxy-types.c++ - printer.capnp.proxy-types.h - printer.h - calculator.h example.cpp ) -target_include_directories(mpexample PUBLIC - ${CAPNP_INCLUDE_DIRECTORY} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} +target_capnp_sources(mpexample ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp + IMPORT_PATHS ${CMAKE_SOURCE_DIR}/include ) -target_link_libraries(mpexample PRIVATE CapnProto::capnp) -target_link_libraries(mpexample PRIVATE CapnProto::capnp-rpc) -target_link_libraries(mpexample PRIVATE CapnProto::kj) -target_link_libraries(mpexample PRIVATE CapnProto::kj-async) +target_include_directories(mpexample PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(mpexample PRIVATE Threads::Threads) -target_link_libraries(mpexample PRIVATE multiprocess) target_link_libraries(mpexample PRIVATE stdc++fs) add_custom_target(example DEPENDS mpexample mpcalculator mpprinter) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b7ce906..52c3519 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,46 +15,21 @@ add_custom_target(tests) add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS tests) if(BUILD_TESTING AND TARGET CapnProto::kj-test) - add_custom_command( - OUTPUT - mp/test/foo.capnp.h - mp/test/foo.capnp.c++ - mp/test/foo.capnp.proxy.h - mp/test/foo.capnp.proxy-server.c++ - mp/test/foo.capnp.proxy-client.c++ - mp/test/foo.capnp.proxy-types.c++ - mp/test/foo.capnp.proxy-types.h - COMMAND mpgen "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/mp/test/foo.capnp" "${CMAKE_SOURCE_DIR}/include" "${capnp_PREFIX}/include" - DEPENDS mp/test/foo.capnp mpgen - ) - set_property(SOURCE ${MP_PROXY_HDRS} PROPERTY GENERATED 1) add_executable(mptest ${MP_PROXY_HDRS} - mp/test/foo.capnp.h - mp/test/foo.capnp.c++ - mp/test/foo.capnp.proxy.h - mp/test/foo.capnp.proxy-server.c++ - mp/test/foo.capnp.proxy-client.c++ - mp/test/foo.capnp.proxy-types.c++ - mp/test/foo.capnp.proxy-types.h mp/test/foo-types.h mp/test/foo.h mp/test/test.cpp ) - target_include_directories(mptest PUBLIC - ${CAPNP_INCLUDE_DIRECTORY} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} + include(${PROJECT_SOURCE_DIR}/cmake/LibmultiprocessMacros.cmake) + target_capnp_sources(mptest ${CMAKE_CURRENT_SOURCE_DIR} mp/test/foo.capnp + IMPORT_PATHS ${CMAKE_SOURCE_DIR}/include ) - target_link_libraries(mptest PRIVATE CapnProto::capnp) - target_link_libraries(mptest PRIVATE CapnProto::capnp-rpc) - target_link_libraries(mptest PRIVATE CapnProto::kj) - target_link_libraries(mptest PRIVATE CapnProto::kj-async) + target_include_directories(mptest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(mptest PRIVATE CapnProto::kj-test) target_link_libraries(mptest PRIVATE Threads::Threads) - target_link_libraries(mptest PRIVATE multiprocess) add_dependencies(tests mptest) add_test(NAME mptest COMMAND mptest)