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
115 changes: 46 additions & 69 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ project("Libmultiprocess" CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)

find_package(CapnProto REQUIRED)
find_package(Threads REQUIRED)

option(Libmultiprocess_ENABLE_CLANG_TIDY "Run clang-tidy with the compiler." OFF)
if(Libmultiprocess_ENABLE_CLANG_TIDY)
find_program(CLANG_TIDY_EXECUTABLE NAMES clang-tidy)
Expand All @@ -17,61 +20,30 @@ if(Libmultiprocess_ENABLE_CLANG_TIDY)
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXECUTABLE}")
endif()

include(CMakePushCheckState)
include(CheckCXXSourceCompiles)
include(GNUInstallDirs)
find_package(CapnProto REQUIRED)
find_package(Threads REQUIRED)

include("cmake/capnp_compat.cmake")
include("cmake/pthread_checks.cmake")
include(GNUInstallDirs)

cmake_push_check_state()
set(CMAKE_REQUIRED_LIBRARIES Threads::Threads)
check_cxx_source_compiles("
#include <pthread.h>
int main(int argc, char** argv)
{
char thread_name[16];
return pthread_getname_np(pthread_self(), thread_name, sizeof(thread_name));
}"
HAVE_PTHREAD_GETNAME_NP)

check_cxx_source_compiles("
#include <cstdint>
#include <pthread.h>
int main(int argc, char** argv)
{
uint64_t tid;
pthread_threadid_np(NULL, &tid);
return 0;
}"
HAVE_PTHREAD_THREADID_NP)

check_cxx_source_compiles("
#include <pthread.h>
#include <pthread_np.h>
int main(int argc, char** argv)
{
return pthread_getthreadid_np();
}"
HAVE_PTHREAD_GETTHREADID_NP)
cmake_pop_check_state()
# Generated C++ preprocessor defines
configure_file(include/mp/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/mp/config.h")

# Generated C++ Capn'Proto schema files
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
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
${CAPNP_INCLUDE_DIRECTORY})

# libmultiprocess.a runtime library
set(MP_PUBLIC_HEADERS
${MP_PROXY_HDRS}
include/mp/proxy-io.h
include/mp/proxy-types.h
include/mp/proxy.h
include/mp/util.h)

add_library(multiprocess STATIC
${MP_PROXY_SRCS}
${MP_PUBLIC_HEADERS}
Expand All @@ -92,26 +64,8 @@ set_target_properties(multiprocess PROPERTIES
install(TARGETS multiprocess EXPORT LibTargets
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 LibTargets
NAMESPACE Libmultiprocess::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess COMPONENT lib)
include(CMakePackageConfigHelpers)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/cmake/LibmultiprocessLibConfig.cmake.in
LibmultiprocessLibConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake
NO_SET_AND_CHECK_MACRO)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/LibmultiprocessLibConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake 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)

# mpgen code generator
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>)
Expand All @@ -128,32 +82,55 @@ set_target_properties(mpgen PROPERTIES
install(TARGETS mpgen EXPORT BinTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mp COMPONENT bin)

# makefile include to invoke mpgen code generator, for downstream Make projects
install(FILES "include/mpgen.mk"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT bin)

# pkg-config module to build against libmultiprocess library, for downstream autoconf projects
configure_file(pkgconfig/libmultiprocess.pc.in "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/libmultiprocess.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/libmultiprocess.pc"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT lib)

# cmake include to invoke mpgen code generator, for downstream CMake projects
install(
FILES
${CMAKE_CURRENT_SOURCE_DIR}/cmake/TargetCapnpSources.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess COMPONENT bin)

# CMake target import files, for downstream CMake projects
install(EXPORT BinTargets
NAMESPACE Libmultiprocess::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess COMPONENT bin)
install(EXPORT LibTargets
NAMESPACE Libmultiprocess::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess COMPONENT lib)

# CMake find_package config file, for downstream CMake projects
include(CMakePackageConfigHelpers)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/cmake/LibmultiprocessBinConfig.cmake.in
LibmultiprocessBinConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake
${PROJECT_SOURCE_DIR}/cmake/Config.cmake.in
LibmultiprocessConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess
NO_SET_AND_CHECK_MACRO)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/LibmultiprocessBinConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake COMPONENT bin)
install(
FILES
${CMAKE_CURRENT_SOURCE_DIR}/cmake/TargetCapnpSources.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess COMPONENT bin)
${CMAKE_CURRENT_BINARY_DIR}/LibmultiprocessConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess
COMPONENT common)

# Makefile targets to support "make install-bin" "make install-lib"
add_custom_target(install-bin
COMMAND ${CMAKE_COMMAND} -DCOMPONENT=bin -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
COMMAND ${CMAKE_COMMAND} -DCOMPONENT=common -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
VERBATIM)
add_dependencies(install-bin mpgen)
add_custom_target(install-lib
COMMAND ${CMAKE_COMMAND} -DCOMPONENT=lib -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
COMMAND ${CMAKE_COMMAND} -DCOMPONENT=common -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
VERBATIM)
add_dependencies(install-lib multiprocess)

configure_file(include/mp/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/mp/config.h")
configure_file(pkgconfig/libmultiprocess.pc.in "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/libmultiprocess.pc" @ONLY)

# Example and test subdirectories
add_subdirectory(example EXCLUDE_FROM_ALL)
add_subdirectory(test EXCLUDE_FROM_ALL)
30 changes: 30 additions & 0 deletions cmake/Config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@PACKAGE_INIT@

# CMake find_package compatible package file, for downstream CMake projects
#
# Based on https://cmake.org/cmake/help/latest/guide/importing-exporting/index.html#adding-components

set(_Libmultiprocess_supported_components Bin Lib)

# If no components specified, include all components.
list(LENGTH Libmultiprocess_FIND_COMPONENTS Libmultiprocess_FIND_COMPONENTS_len)
if(Libmultiprocess_FIND_COMPONENTS_len EQUAL 0)
set(Libmultiprocess_FIND_COMPONENTS ${_Libmultiprocess_supported_components})
endif()

if ("Bin" IN_LIST Libmultiprocess_FIND_COMPONENTS)
include("${CMAKE_CURRENT_LIST_DIR}/TargetCapnpSources.cmake")
endif()

if ("Lib" IN_LIST Libmultiprocess_FIND_COMPONENTS)
include(CMakeFindDependencyMacro)
find_dependency(CapnProto)
endif()

foreach(_comp ${Libmultiprocess_FIND_COMPONENTS})
if (NOT _comp IN_LIST _Libmultiprocess_supported_components)
set(Libmultiprocess_FOUND False)
set(Libmultiprocess_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/${_comp}Targets.cmake")
endforeach()
6 changes: 0 additions & 6 deletions cmake/LibmultiprocessBinConfig.cmake.in

This file was deleted.

8 changes: 0 additions & 8 deletions cmake/LibmultiprocessLibConfig.cmake.in

This file was deleted.

41 changes: 41 additions & 0 deletions cmake/pthread_checks.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright (c) 2024 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

# Define HAVE_PTHREAD_* variables depending on what pthread functions are
# available.

include(CMakePushCheckState)
include(CheckCXXSourceCompiles)

cmake_push_check_state()
set(CMAKE_REQUIRED_LIBRARIES Threads::Threads)
check_cxx_source_compiles("
#include <pthread.h>
int main(int argc, char** argv)
{
char thread_name[16];
return pthread_getname_np(pthread_self(), thread_name, sizeof(thread_name));
}"
HAVE_PTHREAD_GETNAME_NP)

check_cxx_source_compiles("
#include <cstdint>
#include <pthread.h>
int main(int argc, char** argv)
{
uint64_t tid;
pthread_threadid_np(NULL, &tid);
return 0;
}"
HAVE_PTHREAD_THREADID_NP)

check_cxx_source_compiles("
#include <pthread.h>
#include <pthread_np.h>
int main(int argc, char** argv)
{
return pthread_getthreadid_np();
}"
HAVE_PTHREAD_GETTHREADID_NP)
cmake_pop_check_state()
32 changes: 32 additions & 0 deletions doc/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,35 @@ make
make check # Optionally build and run tests
make install
```

To build with libmultiprocess in a CMake project can specify:

```cmake
find_package(Libmultiprocess)
target_capnp_sources(mytarget ${CMAKE_CURRENT_SOURCE_DIR} myschema.capnp)
```

Which will locate the libmultiprocess cmake package, and call the
`target_capnp_sources` function to generate C++ files and link them into a
library or executable target. See `example/CMakeLists.txt` for a complete
example.

To build with libmultiprocess in a non-CMake project can use installed
`<prefix>/include/mpgen.mk` Makefile rule to generate C++ files, and
`<prefix>/lib/pkgconfig/libmultiprocess.pc` pkg-config definition to link
against the runtime library.

For cross-compilation, it may be useful to build the runtime library and code
generation binaries separately, which can be done with:

```sh
make install-bin # install bin/mpgen and related files
make install-lib # install lib/libmultiprocess.a and related files
```

It is also possible to import CMake targets separately with:

```cmake
find_package(Libmultiprocess COMPONENTS Bin)
find_package(Libmultiprocess COMPONENTS Lib)
```