Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ add_library(multiprocess STATIC
${MP_PUBLIC_HEADERS}
src/mp/proxy.cpp
$<TARGET_OBJECTS:util>)
add_library(Libmultiprocess::multiprocess ALIAS multiprocess)
target_include_directories(multiprocess PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
Expand All @@ -88,20 +89,31 @@ target_link_libraries(multiprocess PRIVATE CapnProto::kj)
target_link_libraries(multiprocess PRIVATE CapnProto::kj-async)
set_target_properties(multiprocess PROPERTIES
PUBLIC_HEADER "${MP_PUBLIC_HEADERS}")
install(TARGETS multiprocess EXPORT libmultiprocess-lib
install(TARGETS multiprocess EXPORT LibmultiprocessTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mp COMPONENT lib)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/libmultiprocess.pc"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT lib)
install(EXPORT libmultiprocess-lib
install(EXPORT LibmultiprocessTargets
NAMESPACE Libmultiprocess::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake COMPONENT lib)
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess COMPONENT lib)
include(CMakePackageConfigHelpers)
configure_package_config_file(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there may be need to be some additional changes to this file to make the package "relocatable" according to https://cmake.org/cmake/help/latest/guide/importing-exporting/index.html#creating-relocatable-packages.

Specifically the PUBLIC include directory $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> on line 84 above and ${CAPNP_INCLUDE_DIRECTORY}` on line 85 look like they will add include paths from the build system to the exported targets, and potentially cause problems in some build configurations. This might not be a problem for the bitcoin depends build, though, because it is building everything on one system.

Possible fixes to replace the $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> line might be:

Possible fix to replace the ${CAPNP_INCLUDE_DIRECTORY} line might be to change target_link_libraries(multiprocess PRIVATE CapnProto::capnp) from PRIVATE to PUBLIC, assuming that making capnproto a public dependency will cause cmake to propagate the necessary includes.

${PROJECT_SOURCE_DIR}/cmake/LibmultiprocessConfig.cmake.in
LibmultiprocessConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess
NO_SET_AND_CHECK_MACRO)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/LibmultiprocessConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess COMPONENT lib)
add_custom_target(install-lib
COMMAND ${CMAKE_COMMAND} -DCOMPONENT=lib -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
VERBATIM)
add_dependencies(install-lib multiprocess)

add_executable(mpgen src/mp/gen.cpp $<TARGET_OBJECTS:util>)
add_executable(Libmultiprocess::mpgen ALIAS mpgen)
target_include_directories(mpgen PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>)
target_include_directories(mpgen PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_link_libraries(mpgen PRIVATE CapnProto::capnp)
Expand All @@ -113,14 +125,25 @@ set_target_properties(mpgen PROPERTIES
INSTALL_RPATH_USE_LINK_PATH TRUE)
set_target_properties(mpgen PROPERTIES
PUBLIC_HEADER include/mp/proxy.capnp)
install(TARGETS mpgen EXPORT libmultiprocess-bin
install(TARGETS mpgen EXPORT LibmultiprocessGenTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mp COMPONENT bin)
install(FILES "include/mpgen.mk"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT bin)
install(EXPORT libmultiprocess-bin
install(EXPORT LibmultiprocessGenTargets
NAMESPACE Libmultiprocess::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake COMPONENT bin)
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LibmultiprocessGen COMPONENT bin)
include(CMakePackageConfigHelpers)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/cmake/LibmultiprocessGenConfig.cmake.in
LibmultiprocessGenConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LibmultiprocessGen
NO_SET_AND_CHECK_MACRO)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/LibmultiprocessGenConfig.cmake
${CMAKE_CURRENT_SOURCE_DIR}/cmake/LibmultiprocessMacros.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LibmultiprocessGen COMPONENT bin)
add_custom_target(install-bin
COMMAND ${CMAKE_COMMAND} -DCOMPONENT=bin -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
VERBATIM)
Expand Down
8 changes: 8 additions & 0 deletions cmake/LibmultiprocessConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@PACKAGE_INIT@

include(CMakeFindDependencyMacro)
find_dependency(CapnProto)

include("${CMAKE_CURRENT_LIST_DIR}/LibmultiprocessTargets.cmake")

check_required_components(Libmultiprocess)
6 changes: 6 additions & 0 deletions cmake/LibmultiprocessGenConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/LibmultiprocessGenTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/LibmultiprocessMacros.cmake")

check_required_components(LibmultiprocessGen)
94 changes: 94 additions & 0 deletions cmake/LibmultiprocessMacros.cmake
Original file line number Diff line number Diff line change
@@ -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 <lib/schema.capnp.h>

And if include_prefix is /home/src/lib, generated includes look like:

#include <schema.capnp.h>

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 $<BUILD_INTERFACE:${build_include_prefix}>)

if(TARGET Libmultiprocess::multiprocess)
target_link_libraries(${target} PRIVATE Libmultiprocess::multiprocess)
endif()
endfunction()
140 changes: 10 additions & 130 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
33 changes: 4 additions & 29 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down