Unverified Commit 215ef000 authored by Kenton Varda's avatar Kenton Varda Committed by GitHub

Merge pull request #575 from harrishancock/autotools-installs-cmake-config

Autotools installs CMake package config files
parents 1097343d 0a4a6ce7
......@@ -56,7 +56,9 @@
/c++/build-aux/
/c++/capnp
/c++/capnp-evolution-test
/c++/*.pc
/c++/cmake/CapnProtoConfig.cmake
/c++/cmake/CapnProtoConfigVersion.cmake
/c++/pkgconfig/*.pc
/c++/capnp-test
/c++/capnpc-c++
/c++/capnpc-capnp
......
......@@ -81,11 +81,17 @@ add_subdirectory(src)
# Install ======================================================================
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/cmake/CapnProtoConfigVersion.cmake"
VERSION ${VERSION}
COMPATIBILITY AnyNewerVersion
)
# We used to use write_basic_package_version_file(), but since the autotools build needs to install
# a config version script as well, I copied the AnyNewerVersion template from my CMake Modules
# directory to Cap'n Proto's cmake/ directory (alternatively, we could make the autotools build
# depend on CMake).
#
# We might as well use the local copy of the template. In the future we can modify the project's
# version compatibility policy just by changing that file.
set(PACKAGE_VERSION ${VERSION})
configure_file(cmake/CapnProtoConfigVersion.cmake.in cmake/CapnProtoConfigVersion.cmake @ONLY)
set(CONFIG_PACKAGE_LOCATION ${CMAKE_INSTALL_LIBDIR}/cmake/CapnProto)
configure_package_config_file(cmake/CapnProtoConfig.cmake.in
......@@ -120,23 +126,26 @@ if(NOT MSVC) # Don't install pkg-config files when building with MSVC
set(PTHREAD_CFLAGS "-pthread")
set(STDLIB_FLAG) # TODO: Unsupported
configure_file(kj.pc.in "${CMAKE_CURRENT_BINARY_DIR}/kj.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/kj.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
configure_file(capnp.pc.in "${CMAKE_CURRENT_BINARY_DIR}/capnp.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/capnp.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
set(CAPNP_PKG_CONFIG_FILES
pkgconfig/kj.pc
pkgconfig/capnp.pc
)
if(NOT CAPNP_LITE)
configure_file(kj-async.pc.in "${CMAKE_CURRENT_BINARY_DIR}/kj-async.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/kj-async.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
configure_file(capnp-rpc.pc.in "${CMAKE_CURRENT_BINARY_DIR}/capnp-rpc.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/capnp-rpc.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
configure_file(capnp-json.pc.in "${CMAKE_CURRENT_BINARY_DIR}/capnp-json.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/capnp-json.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
list(APPEND CAPNP_PKG_CONFIG_FILES
pkgconfig/kj-async.pc
pkgconfig/kj-http.pc
pkgconfig/kj-test.pc
pkgconfig/capnp-rpc.pc
pkgconfig/capnp-json.pc
)
endif()
foreach(pcfile ${CAPNP_PKG_CONFIG_FILES})
configure_file(${pcfile}.in "${CMAKE_CURRENT_BINARY_DIR}/${pcfile}" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${pcfile}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endforeach()
unset(STDLIB_FLAG)
unset(PTHREAD_CFLAGS)
unset(includedir)
......
......@@ -33,8 +33,6 @@ EXTRA_DIST = \
src/capnp/testdata/packedflat \
CMakeLists.txt \
cmake/FindCapnProto.cmake \
cmake/CapnProtoConfig.cmake.in \
cmake/CapnProtoMacros.cmake \
src/CMakeLists.txt \
src/kj/CMakeLists.txt \
src/capnp/CMakeLists.txt
......@@ -114,7 +112,12 @@ includekjcompatdir = $(includekjdir)/compat
dist_includecapnp_DATA = $(public_capnpc_inputs)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = capnp.pc capnp-rpc.pc capnp-json.pc kj.pc kj-async.pc
pkgconfig_DATA = $(CAPNP_PKG_CONFIG_FILES)
cmakeconfigdir = $(libdir)/cmake/CapnProto
cmakeconfig_DATA = $(CAPNP_CMAKE_CONFIG_FILES) \
cmake/CapnProtoMacros.cmake \
cmake/CapnProtoTargets.cmake
noinst_HEADERS = \
src/kj/miniposix.h
......
# Cap'n Proto CMake Package Configuration
#
# When configured and installed, this file enables client projects to find Cap'n Proto using
# CMake's find_package() command. It adds imported targets in the CapnProto:: namespace, such as
# CapnProto::kj, CapnProto::capnp, etc. (one target for each file in pkgconfig/*.pc.in), defines
# the capnp_generate_cpp() function, and exposes some variables for compatibility with the original
# FindCapnProto.cmake module.
#
# Example usage:
# find_package(CapnProto)
# capnp_generate_cpp(CAPNP_SRCS CAPNP_HDRS schema.capnp)
# include_directories(${CMAKE_CURRENT_BINARY_DIR})
# add_executable(foo main.cpp ${CAPNP_SRCS})
# target_link_libraries(foo CapnProto::capnp)
# target_link_libraries(foo PRIVATE CapnProto::capnp)
# target_include_directories(foo PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
#
# If you are using RPC features, use 'CapnProto::capnp-rpc' in the target_link_libraries() call.
#
# If you are using RPC features, use 'CapnProto::capnp-rpc'
# in target_link_libraries call.
# Paths to `capnp` and `capnpc-c++` are exposed in the following variables:
# CAPNP_EXECUTABLE
# Path to the `capnp` tool (can be set to override).
# CAPNPC_CXX_EXECUTABLE
# Path to the `capnpc-c++` tool (can be set to override).
#
# For FindCapnProto.cmake compatibility, the following variables are also provided. Please prefer
# using the imported targets in new CMake code.
# CAPNP_INCLUDE_DIRS
# Include directories for the library's headers.
# CANP_LIBRARIES
# The Cap'n Proto library paths.
# CAPNP_LIBRARIES_LITE
# Paths to only the 'lite' libraries.
# CAPNP_DEFINITIONS
# Compiler definitions required for building with the library.
# CAPNP_FOUND
# Set if the libraries have been located (prefer using CapnProto_FOUND in new code).
#
@PACKAGE_INIT@
set(CapnProto_VERSION @VERSION@)
set(CAPNP_EXECUTABLE $<TARGET_FILE:CapnProto::capnp_tool>)
set(CAPNPC_CXX_EXECUTABLE $<TARGET_FILE:CapnProto::capnpc_cpp>)
set(CAPNP_EXECUTABLE $<TARGET_FILE:CapnProto::capnp_tool>
CACHE FILEPATH "Location of capnp executable")
set(CAPNPC_CXX_EXECUTABLE $<TARGET_FILE:CapnProto::capnpc_cpp>
CACHE FILEPATH "Location of capnpc-c++ executable")
set(CAPNP_INCLUDE_DIRECTORY "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@")
# work around http://public.kitware.com/Bug/view.php?id=15258
......@@ -25,3 +53,23 @@ endif()
include("${CMAKE_CURRENT_LIST_DIR}/CapnProtoTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/CapnProtoMacros.cmake")
# FindCapnProto.cmake provides dependency information via several CAPNP_-prefixed variables. New
# code should not rely on these variables, but prefer linking directly to the imported targets we
# now provide. However, we should still set these variables to ease the transition for projects
# which currently depend on the find-module.
set(CAPNP_INCLUDE_DIRS ${CAPNP_INCLUDE_DIRECTORY})
# No need to list all libraries, just the leaves of the dependency tree.
set(CAPNP_LIBRARIES_LITE CapnProto::capnp)
set(CAPNP_LIBRARIES CapnProto::capnp-rpc CapnProto::capnp-json
CapnProto::kj-http CapnProto::kj-test)
set(CAPNP_DEFINITIONS)
if(TARGET CapnProto::capnp AND NOT TARGET CapnProto::capnp-rpc)
set(CAPNP_DEFINITIONS -DCAPNP_LITE)
endif()
set(CAPNP_FOUND ${CapnProto_FOUND})
# This is a copy of /usr/share/cmake-3.5/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in, with
# the following change:
# - @CVF_VERSION renamed to @PACKAGE_VERSION@. Autoconf defines a PACKAGE_VERSION
# output variable for us, so might as well take advantage of that.
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version.
# The variable PACKAGE_VERSION must be set before calling configure_file().
set(PACKAGE_VERSION "@PACKAGE_VERSION@")
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
return()
endif()
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@")
math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()
......@@ -3,12 +3,12 @@
# Example usage:
# find_package(CapnProto)
# capnp_generate_cpp(CAPNP_SRCS CAPNP_HDRS schema.capnp)
# include_directories(${CMAKE_CURRENT_BINARY_DIR})
# add_executable(foo main.cpp ${CAPNP_SRCS})
# target_link_libraries(foo CapnProto::capnp-rpc)
# target_link_libraries(foo PRIVATE CapnProto::capnp-rpc)
# target_include_directories(foo PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
#
# If you are using not using the RPC features you can use
# 'CapnProto::capnp' in target_link_libraries call
# If you are not using the RPC features you can use 'CapnProto::capnp' in the
# target_link_libraries call
#
# Configuration variables (optional):
# CAPNPC_OUTPUT_DIR
......
# This CMake script adds imported targets for each shared library and executable distributed by
# Cap'n Proto's autotools build.
#
# This file IS NOT USED by the CMake build! The CMake build generates its own version of this script
# from its set of exported targets. I used such a generated script as a reference when writing this
# one.
#
# The set of library targets provided by this script is automatically generated from the list of .pc
# files maintained in configure.ac. The set of executable targets is hard-coded in this file.
#
# You can request that this script print debugging information by invoking cmake with:
#
# -DCapnProto_DEBUG=ON
#
# TODO(someday): Distinguish between debug and release builds. I.e., set IMPORTED_LOCATION_RELEASE
# rather than IMPORTED_LOCATION, etc., if this installation was configured as a release build. But
# how do we tell? grep for -g in CXXFLAGS?
if(CMAKE_VERSION VERSION_LESS 3.1)
message(FATAL_ERROR "CMake >= 3.1 required")
endif()
set(forwarded_config_flags)
if(CapnProto_FIND_QUIETLY)
list(APPEND forwarded_config_flags QUIET)
endif()
if(CapnProto_FIND_REQUIRED)
list(APPEND forwarded_config_flags REQUIRED)
endif()
# If the consuming project called find_package(CapnProto) with the QUIET or REQUIRED flags, forward
# them to calls to find_package(PkgConfig) and pkg_check_modules(). Note that find_dependency()
# would do this for us in the former case, but there is no such forwarding wrapper for
# pkg_check_modules().
find_package(PkgConfig ${forwarded_config_flags})
if(NOT ${PkgConfig_FOUND})
# If we're here, the REQUIRED flag must not have been passed, else we would have had a fatal
# error. Nevertheless, a diagnostic for this case is probably nice.
if(NOT CapnProto_FIND_QUIETLY)
message(WARNING "pkg-config cannot be found")
endif()
set(CapnProto_FOUND OFF)
return()
endif()
function(_capnp_import_pkg_config_target target)
# Add an imported library target named CapnProto::${target}, using the output of various
# invocations of `pkg-config ${target}`. The generated imported library target tries to mimic the
# behavior of a real CMake-generated imported target as closely as possible.
#
# Usage: _capnp_import_pkg_config_target(target <all Cap'n Proto targets>)
set(all_targets ${ARGN})
pkg_check_modules(${target} ${forwarded_config_flags} ${target})
if(NOT ${${target}_FOUND})
if(NOT CapnProto_FIND_QUIETLY)
message(WARNING "CapnProtoConfig.cmake was configured to search for ${target}.pc, but pkg-config cannot find it. Ignoring this target.")
endif()
return()
endif()
if(CapnProto_DEBUG)
# Dump the information pkg-config discovered.
foreach(var VERSION LIBRARY_DIRS LIBRARIES LDFLAGS_OTHER INCLUDE_DIRS CFLAGS_OTHER)
message(STATUS "${target}_${var} = ${${target}_${var}}")
endforeach()
endif()
if(NOT ${${target}_VERSION} VERSION_EQUAL ${CapnProto_VERSION})
if(NOT CapnProto_FIND_QUIETLY)
message(WARNING "CapnProtoConfig.cmake was configured to search for version ${CapnProto_VERSION}, but ${target} version ${${target}_VERSION} was found. Ignoring this target.")
endif()
return()
endif()
# Make an educated guess as to what the target's .so and .a filenames must be.
set(target_name_shared
${CMAKE_SHARED_LIBRARY_PREFIX}${target}-${CapnProto_VERSION}${CMAKE_SHARED_LIBRARY_SUFFIX})
set(target_name_static
${CMAKE_STATIC_LIBRARY_PREFIX}${target}${CMAKE_STATIC_LIBRARY_SUFFIX})
# Find the actual target's file. find_library() sets a cache variable, so I made the variable name
# unique-ish.
find_library(CapnProto_${target}_IMPORTED_LOCATION
NAMES ${target_name_shared} ${target_name_static} # prefer libfoo-version.so over libfoo.a
PATHS ${${target}_LIBRARY_DIRS}
NO_DEFAULT_PATH
)
if(NOT CapnProto_${target}_IMPORTED_LOCATION)
# Not an error if the library doesn't exist -- we may have found a lite mode installation.
if(CapnProto_DEBUG)
message(STATUS "${target} library does not exist")
endif()
return()
endif()
# Record some information about this target -- shared versus static, location and soname -- which
# we'll use to build our imported target later.
set(target_location ${CapnProto_${target}_IMPORTED_LOCATION})
get_filename_component(target_name "${target_location}" NAME)
set(target_type STATIC)
set(imported_soname_property)
if(target_name STREQUAL ${target_name_shared})
set(target_type SHARED)
set(imported_soname_property IMPORTED_SONAME ${target_name})
endif()
# Each library dependency of the target is either the target itself, a sibling Cap'n Proto
# library, or a system library. We ignore the first case by removing this target from the
# dependencies. The remaining dependencies are either passed through or, if they are a sibling
# Cap'n Proto library, prefixed with `CapnProto::`.
set(dependencies ${${target}_LIBRARIES})
list(REMOVE_ITEM dependencies ${target})
set(target_interface_libs)
foreach(dependency ${dependencies})
list(FIND all_targets ${dependency} target_index)
# TODO(cleanup): CMake >= 3.3 lets us write: `if(NOT ${dependency} IN_LIST all_targets)`
if(target_index EQUAL -1)
list(APPEND target_interface_libs ${dependency})
else()
list(APPEND target_interface_libs CapnProto::${dependency})
endif()
endforeach()
add_library(CapnProto::${target} ${target_type} IMPORTED)
set_target_properties(CapnProto::${target} PROPERTIES
${imported_soname_property}
IMPORTED_LOCATION "${target_location}"
INTERFACE_COMPILE_FEATURES "cxx_constexpr"
INTERFACE_COMPILE_OPTIONS "${${target}_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${${target}_INCLUDE_DIRS}"
# I'm dumping LDFLAGS_OTHER in with the libraries because there exists no
# INTERFACE_LINK_OPTIONS. See https://gitlab.kitware.com/cmake/cmake/issues/16543.
INTERFACE_LINK_LIBRARIES "${target_interface_libs};${${target}_LDFLAGS_OTHER}"
)
if(CapnProto_DEBUG)
# Dump all the properties we generated for the imported target.
foreach(prop
IMPORTED_LOCATION
IMPORTED_SONAME
INTERFACE_COMPILE_FEATURES
INTERFACE_COMPILE_OPTIONS
INTERFACE_INCLUDE_DIRECTORIES
INTERFACE_LINK_LIBRARIES)
get_target_property(value CapnProto::${target} ${prop})
message(STATUS "CapnProto::${target} ${prop} = ${value}")
endforeach()
endif()
endfunction()
# ========================================================================================
# Imported library targets
# Build a list of targets to search for from the list of .pc files.
# I.e. [somewhere/foo.pc, somewhere/bar.pc] -> [foo, bar]
set(library_targets)
foreach(filename ${CAPNP_PKG_CONFIG_FILES})
get_filename_component(target ${filename} NAME_WE)
list(APPEND library_targets ${target})
endforeach()
# Try to add an imported library target CapnProto::foo for each foo.pc distributed with Cap'n Proto.
foreach(target ${library_targets})
_capnp_import_pkg_config_target(${target} ${library_targets})
endforeach()
# Handle lite-mode and no libraries found cases. It is tempting to set a CapnProto_LITE variable
# here, but the real CMake-generated implementation does no such thing -- we'd need to set it in
# CapnProtoConfig.cmake.in itself.
if(TARGET CapnProto::capnp AND TARGET CapnProto::kj)
if(NOT TARGET CapnProto::capnp-rpc)
if(NOT CapnProto_FIND_QUIETLY)
message(STATUS "Found an installation of Cap'n Proto lite. Executable and library targets beyond libkj and libcapnp will be unavailable.")
endif()
# Lite mode doesn't include the executables, so return here.
return()
endif()
else()
# If we didn't even find capnp or kj, then we didn't find anything usable.
set(CapnProto_FOUND OFF)
return()
endif()
# ========================================================================================
# Imported executable targets
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
# Add executable targets for the capnp compiler and plugins. This list must be kept manually in sync
# with the rest of the project.
add_executable(CapnProto::capnp_tool IMPORTED)
set_target_properties(CapnProto::capnp_tool PROPERTIES
IMPORTED_LOCATION "${_IMPORT_PREFIX}/bin/capnp${CMAKE_EXECUTABLE_SUFFIX}"
)
add_executable(CapnProto::capnpc_cpp IMPORTED)
set_target_properties(CapnProto::capnpc_cpp PROPERTIES
IMPORTED_LOCATION "${_IMPORT_PREFIX}/bin/capnpc-c++${CMAKE_EXECUTABLE_SUFFIX}"
)
add_executable(CapnProto::capnpc_capnp IMPORTED)
set_target_properties(CapnProto::capnpc_capnp PROPERTIES
IMPORTED_LOCATION "${_IMPORT_PREFIX}/bin/capnpc-capnp${CMAKE_EXECUTABLE_SUFFIX}"
)
......@@ -105,5 +105,35 @@ AC_SUBST([STDLIB_FLAG])
LIBS="$PTHREAD_LIBS $LIBS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
AC_CONFIG_FILES([Makefile capnp.pc capnp-rpc.pc capnp-json.pc kj.pc kj-async.pc])
AC_DEFUN([CAPNP_PKG_CONFIG_FILES], [ \
pkgconfig/capnp.pc \
pkgconfig/capnp-rpc.pc \
pkgconfig/capnp-json.pc \
pkgconfig/kj.pc \
pkgconfig/kj-async.pc \
pkgconfig/kj-http.pc \
pkgconfig/kj-test.pc \
])
AC_DEFUN([CAPNP_CMAKE_CONFIG_FILES], [ \
cmake/CapnProtoConfig.cmake \
cmake/CapnProtoConfigVersion.cmake \
])
[CAPNP_PKG_CONFIG_FILES]="CAPNP_PKG_CONFIG_FILES"
[CAPNP_CMAKE_CONFIG_FILES]="CAPNP_CMAKE_CONFIG_FILES"
AC_SUBST([CAPNP_PKG_CONFIG_FILES])
AC_SUBST([CAPNP_CMAKE_CONFIG_FILES])
# CapnProtoConfig.cmake.in needs these PACKAGE_* output variables.
PACKAGE_INIT="set([CAPNP_PKG_CONFIG_FILES] CAPNP_PKG_CONFIG_FILES)"
PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR="${CMAKE_CURRENT_LIST_DIR}/../../include"
AC_SUBST([PACKAGE_INIT])
AC_SUBST([PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR])
# CapnProtoConfigVersion.cmake.in needs PACKAGE_VERSION (already defined by AC_INIT) and
# CMAKE_SIZEOF_VOID_P output variables.
AC_CHECK_SIZEOF([void *])
AC_SUBST(CMAKE_SIZEOF_VOID_P, $ac_cv_sizeof_void_p)
AC_CONFIG_FILES([Makefile] CAPNP_PKG_CONFIG_FILES CAPNP_CMAKE_CONFIG_FILES)
AC_OUTPUT
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: KJ HTTP Library
Description: Basic utility library called KJ (HTTP part)
Version: @VERSION@
Libs: -L${libdir} -lkj-http @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ @STDLIB_FLAG@
Requires: kj-async = @VERSION@
Cflags: -I${includedir} @PTHREAD_CFLAGS@ @STDLIB_FLAG@ @CAPNP_LITE_FLAG@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: KJ Test Framework
Description: Basic utility library called KJ (test part)
Version: @VERSION@
Libs: -L${libdir} -lkj-test @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ @STDLIB_FLAG@
Requires: kj = @VERSION@
Cflags: -I${includedir} @PTHREAD_CFLAGS@ @STDLIB_FLAG@ @CAPNP_LITE_FLAG@
......@@ -23,13 +23,16 @@ find_package(CapnProto CONFIG REQUIRED)
capnp_generate_cpp(addressbookSources addressbookHeaders addressbook.capnp)
add_executable(addressbook addressbook.c++ ${addressbookSources})
target_link_libraries(addressbook CapnProto::capnp)
target_link_libraries(addressbook PRIVATE CapnProto::capnp)
target_include_directories(addressbook PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
capnp_generate_cpp(calculatorSources calculatorHeaders calculator.capnp)
add_executable(calculator-client calculator-client.c++ ${calculatorSources})
add_executable(calculator-server calculator-server.c++ ${calculatorSources})
target_link_libraries(calculator-client CapnProto::capnp-rpc)
target_link_libraries(calculator-server CapnProto::capnp-rpc)
target_include_directories(calculator-client PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(calculator-server PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
# Don't build the rpc sample if find_package() found an installation of Cap'n Proto lite.
if(TARGET CapnProto::capnp-rpc)
capnp_generate_cpp(calculatorSources calculatorHeaders calculator.capnp)
add_executable(calculator-client calculator-client.c++ ${calculatorSources})
add_executable(calculator-server calculator-server.c++ ${calculatorSources})
target_link_libraries(calculator-client PRIVATE CapnProto::capnp-rpc)
target_link_libraries(calculator-server PRIVATE CapnProto::capnp-rpc)
target_include_directories(calculator-client PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(calculator-server PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
endif()
......@@ -113,6 +113,8 @@ void printAddressBook(int fd) {
}
}
#if !CAPNP_LITE
#include "addressbook.capnp.h"
#include <capnp/message.h>
#include <capnp/serialize-packed.h>
......@@ -260,8 +262,9 @@ void dynamicPrintMessage(int fd, StructSchema schema) {
std::cout << std::endl;
}
#endif // !CAPNP_LITE
int main(int argc, char* argv[]) {
StructSchema schema = Schema::from<AddressBook>();
if (argc != 2) {
std::cerr << "Missing arg." << std::endl;
return 1;
......@@ -269,10 +272,14 @@ int main(int argc, char* argv[]) {
writeAddressBook(1);
} else if (strcmp(argv[1], "read") == 0) {
printAddressBook(0);
#if !CAPNP_LITE
} else if (strcmp(argv[1], "dwrite") == 0) {
StructSchema schema = Schema::from<AddressBook>();
dynamicWriteAddressBook(1, schema);
} else if (strcmp(argv[1], "dread") == 0) {
StructSchema schema = Schema::from<AddressBook>();
dynamicPrintMessage(0, schema);
#endif
} else {
std::cerr << "Invalid arg: " << argv[1] << std::endl;
return 1;
......
......@@ -4,33 +4,31 @@
if(BUILD_TESTING)
include(CTest)
if (EXTERNAL_CAPNP)
if(EXTERNAL_CAPNP)
# Setup CAPNP_GENERATE_CPP for compiling test schemas
find_package(CapnProto CONFIG QUIET)
if (NOT CapnProto_FOUND)
# Try and find the executables from an autotools-based installation
# Setup paths to the schema compiler for generating ${test_capnp_files}
if(NOT EXTERNAL_CAPNP AND NOT CAPNP_LITE)
set(CAPNP_EXECUTABLE $<TARGET_FILE:capnp_tool>)
set(CAPNPC_CXX_EXECUTABLE $<TARGET_FILE:capnpc_cpp>)
else()
# Allow paths to tools to be set with either environment variables or find_program()
if (NOT CAPNP_EXECUTABLE)
if (DEFINED ENV{CAPNP})
set(CAPNP_EXECUTABLE "$ENV{CAPNP}")
else()
find_program(CAPNP_EXECUTABLE capnp)
endif()
if(NOT CapnProto_FOUND)
# No working installation of Cap'n Proto found, so fall back to searching the environment.
#
# We search for the external capnp compiler binaries via $CAPNP, $CAPNPC_CXX, and
# find_program(). find_program() will use various paths in its search, among them
# ${CMAKE_PREFIX_PATH}/bin and $PATH.
if(NOT CAPNP_EXECUTABLE)
if(DEFINED ENV{CAPNP})
set(CAPNP_EXECUTABLE "$ENV{CAPNP}")
else()
find_program(CAPNP_EXECUTABLE capnp)
endif()
endif()
if(NOT CAPNPC_CXX_EXECUTABLE)
if (DEFINED ENV{CAPNPC_CXX})
set(CAPNPC_CXX_EXECUTABLE "$ENV{CAPNPC_CXX}")
else()
# Also search in the same directory that `capnp` was found in
get_filename_component(capnp_dir "${CAPNP_EXECUTABLE}" DIRECTORY)
find_program(CAPNPC_CXX_EXECUTABLE capnpc-c++ HINTS "${capnp_dir}")
endif()
if(NOT CAPNPC_CXX_EXECUTABLE)
if(DEFINED ENV{CAPNPC_CXX})
set(CAPNPC_CXX_EXECUTABLE "$ENV{CAPNPC_CXX}")
else()
# Also search in the same directory that `capnp` was found in
get_filename_component(capnp_dir "${CAPNP_EXECUTABLE}" DIRECTORY)
find_program(CAPNPC_CXX_EXECUTABLE capnpc-c++ HINTS "${capnp_dir}")
endif()
endif()
endif()
......
......@@ -165,6 +165,83 @@ while [ $# -gt 0 ]; do
cd cmake-build
doit cmake -G "Unix Makefiles" ..
doit make -j$PARALLEL check
exit 0
;;
cmake-package )
# Test that a particular configuration of Cap'n Proto can be discovered and configured against
# by a CMake project using the find_package() command. This is currently implemented by
# building the samples against the desired configuration.
#
# Takes one argument, the build configuration, which must be one of:
#
# autotools-shared
# autotools-static
# cmake-shared
# cmake-static
if [ "$#" -ne 2 ]; then
echo "usage: $0 cmake-package CONFIGURATION" >&2
echo " where CONFIGURATION is one of {autotools,cmake}-{static,shared}" >&2
exit 1
fi
CONFIGURATION=$2
WORKSPACE=$(pwd)/cmake-package/$CONFIGURATION
SOURCE_DIR=$(pwd)/c++
rm -rf $WORKSPACE
mkdir -p $WORKSPACE/{build,build-samples,inst}
# Configure
cd $WORKSPACE/build
case "$CONFIGURATION" in
autotools-shared )
autoreconf -i $SOURCE_DIR
doit $SOURCE_DIR/configure --prefix="$WORKSPACE/inst" --disable-static
;;
autotools-static )
autoreconf -i $SOURCE_DIR
doit $SOURCE_DIR/configure --prefix="$WORKSPACE/inst" --disable-shared
;;
cmake-shared )
doit cmake $SOURCE_DIR -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$WORKSPACE/inst" \
-DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=ON
# The CMake build does not currently set the rpath of the capnp compiler tools.
export LD_LIBRARY_PATH="$WORKSPACE/inst/lib"
;;
cmake-static )
doit cmake $SOURCE_DIR -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$WORKSPACE/inst" \
-DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=OFF
;;
* )
echo "Unrecognized cmake-package CONFIGURATION argument, must be {autotools,cmake}-{static,shared}" >&2
exit 1
;;
esac
# Build and install
doit make -j$PARALLEL install
# Configure, build, and execute the samples.
cd $WORKSPACE/build-samples
doit cmake $SOURCE_DIR/samples -G "Unix Makefiles" -DCMAKE_PREFIX_PATH="$WORKSPACE/inst" \
-DCAPNPC_FLAGS=--no-standard-import -DCAPNPC_IMPORT_DIRS="$WORKSPACE/inst/include"
doit make -j$PARALLEL
echo "@@@@ ./addressbook (in various configurations)"
./addressbook write | ./addressbook read
./addressbook dwrite | ./addressbook dread
rm -f /tmp/capnp-calculator-example-$$
./calculator-server unix:/tmp/capnp-calculator-example-$$ &
sleep 0.1
./calculator-client unix:/tmp/capnp-calculator-example-$$
kill %+
wait %+ || true
echo "========================================================================="
echo "Cap'n Proto ($CONFIGURATION) installs a working CMake config package."
echo "========================================================================="
exit 0
;;
exotic )
......@@ -184,6 +261,13 @@ while [ $# -gt 0 ]; do
echo "CMake"
echo "========================================================================="
"$0" cmake
echo "========================================================================="
echo "CMake config packages"
echo "========================================================================="
"$0" cmake-package autotools-shared
"$0" cmake-package autotools-static
"$0" cmake-package cmake-shared
"$0" cmake-package cmake-static
exit 0
;;
clean )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment