Skip to content

Commit

Permalink
Enable cmake install:
Browse files Browse the repository at this point in the history
When building outside of boost, boost_json now supports the install option of cmake.
This patch produces a full, correct install which obeys CMAKE_INSTALL_PREFIX and
creates the correct config.cmake files in order to construct the target Boost::json
This config will automatically find Boost::system using the standard cmake find_package
command
  • Loading branch information
Alexej Harm authored and vinniefalco committed Apr 30, 2020
1 parent 17b4177 commit e74f9bf
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 52 deletions.
21 changes: 21 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,27 @@ jobs:
- COPY="all the environment settings from your job"

include:
# install
- os: linux
dist: bionic
compiler: g++
env: CMAKE_INSTALL_TEST=1
install:
- pip install --user cmake
addons:
apt:
packages:
- libboost-system-dev
- libboost-container-dev
script:
- mkdir __build__ && cd __build__
- cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
- cmake --build . --target install
- cd ../test/cmake_install_test && mkdir __build__ && cd __build__
- cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
- cmake --build .
- cmake --build . --target check

# cmake
- compiler: g++-9
env: CXX=g++-9
Expand Down
113 changes: 71 additions & 42 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ endif()

project(boost_json VERSION "${BOOST_JSON_VERSION}" LANGUAGES CXX)

file(GLOB_RECURSE BOOST_JSON_HEADERS CONFIGURE_DEPENDS
option(BOOST_JSON_STANDALONE "Build boost::json as a standalone library" OFF)
option(BOOST_JSON_BUILD_TESTS "Build boost::json tests" ON)
option(BOOST_JSON_BUILD_EXAMPLES "Build boost::json examples" ON)
option(BOOST_JSON_BUILD_BENCHMARKS "Build boost::json benchmarks" OFF)

file(GLOB_RECURSE BOOST_JSON_HEADERS $<$<VERSION_GREATER_EQUAL:${CMAKE_VERSION},3.12>:CONFIGURE_DEPENDS>
include/boost/*.hpp
include/boost/*.ipp
include/boost/*.natvis
Expand All @@ -28,18 +33,8 @@ set(BOOST_JSON_SOURCES

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

if(${CMAKE_VERSION} VERSION_GREATER 3.7.2)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/include/boost PREFIX "" FILES ${BOOST_JSON_HEADERS})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src PREFIX "" FILES ${BOOST_JSON_SOURCES})
endif()

if(BOOST_JSON_STANDALONE)
# Building standalone, out of Boost superproject tree, without Boost as dependency.
set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard (17 or higher is required)")
if(CMAKE_CXX_STANDARD LESS 17)
message(FATAL_ERROR "Boost.JSON requires C++17 in standalone mode, but CMAKE_CXX_STANDARD is '${CMAKE_CXX_STANDARD}'; please set it to 17 or higher")
endif()
endif()
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/include/boost PREFIX "" FILES ${BOOST_JSON_HEADERS})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src PREFIX "" FILES ${BOOST_JSON_SOURCES})

# TODO: For Boost superproject, do we want to support header-only mode?
# Then, this needs to read `add_library(boost_json INTERFACE)`
Expand All @@ -49,8 +44,13 @@ add_library(Boost::json ALIAS boost_json)

target_compile_features(boost_json PUBLIC cxx_constexpr)

# TODO: For Boost superproject, this may need to be INTERFACE setting
target_include_directories(boost_json PUBLIC include)
# TODO: For Boost superproject, this may need to be INTERFACE setting.
include(GNUInstallDirs)
target_include_directories(boost_json
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)

target_compile_definitions(boost_json PUBLIC BOOST_JSON_NO_LIB=1)

Expand All @@ -60,31 +60,14 @@ else()
target_compile_definitions(boost_json PUBLIC BOOST_JSON_STATIC_LINK=1)
endif()

include(CTest)

option(BOOST_JSON_STANDALONE "Build boost::json as a static standalone library" FALSE)

if(BOOST_JSON_STANDALONE)
# Building standalone, out of Boost superproject tree, without Boost as dependency.
target_compile_definitions(boost_json PUBLIC BOOST_JSON_STANDALONE)

elseif(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
#
# Building as root project, out of Boost superproject tree, with Boost as dependency.
# e.g. on Travis or other CI, or when producing Visual Studio Solution and Projects.
# Building out of Boost superproject tree, without Boost as dependency.
# e.g. for packaging or added with add_subdirectory.
#
if(${CMAKE_VERSION} VERSION_LESS 3.16)
message(FATAL_ERROR "Boost.JSON development requires CMake 3.16 or newer.")
endif()

if (BOOST_JSON_FIND_BOOST)
find_package(Boost REQUIRED COMPONENTS system)
target_link_libraries(boost_json PUBLIC Boost::system)
else()
get_filename_component(BOOST_ROOT ../.. ABSOLUTE)
target_include_directories(boost_json PUBLIC ${BOOST_ROOT})
target_link_directories(boost_json PUBLIC ${BOOST_ROOT}/stage/lib)
endif()
target_compile_definitions(boost_json PUBLIC BOOST_JSON_STANDALONE)
target_compile_features(boost_json PUBLIC cxx_std_17)

elseif(BOOST_SUPERPROJECT_VERSION)
#
# Building as part of Boost superproject tree, with Boost as dependency.
Expand All @@ -95,6 +78,7 @@ elseif(BOOST_SUPERPROJECT_VERSION)
PUBLIC
Boost::assert
Boost::config
Boost::container
Boost::core
Boost::exception
Boost::system
Expand All @@ -103,22 +87,67 @@ elseif(BOOST_SUPERPROJECT_VERSION)

include(BoostInstall)
boost_install(TARGETS boost_json HEADER_DIRECTORY include/)

elseif(BOOST_JSON_IN_BOOST_TREE)
#
# Building inside Boost tree, out of Boost superproject tree, with Boost as dependency.
# e.g. on Travis or other CI, or when producing Visual Studio Solution and Projects.
#
get_filename_component(BOOST_ROOT ../.. ABSOLUTE)
target_include_directories(boost_json PUBLIC ${BOOST_ROOT})
target_link_directories(boost_json PUBLIC ${BOOST_ROOT}/stage/lib)

else()
#
# Out-of-tree, non-standalone build
# Building out of Boost tree, out of Boost superproject tree, with Boost as dependency.
# e.g. for packaging or added with add_subdirectory.
#
find_package(Boost COMPONENTS system)
find_package(Boost REQUIRED COMPONENTS system)
target_link_libraries(boost_json
PUBLIC
Boost::system
)
endif()

if (BUILD_TESTING)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT BOOST_JSON_IN_BOOST_TREE)
set_target_properties(boost_json PROPERTIES EXPORT_NAME json)
install(TARGETS boost_json EXPORT boost_json_targets)

install(EXPORT boost_json_targets
FILE boost_json-targets.cmake
NAMESPACE Boost::
DESTINATION lib/cmake/boost_json
)

include(CMakePackageConfigHelpers)

configure_package_config_file(cmake/config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/boost_json-config.cmake
INSTALL_DESTINATION lib/cmake/boost_json
)

write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/boost_json-config-version.cmake
VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion
)

install(FILES
${CMAKE_CURRENT_BINARY_DIR}/boost_json-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/boost_json-config-version.cmake
DESTINATION lib/cmake/boost_json
)

install(DIRECTORY include/ DESTINATION include)
endif()

if(BOOST_JSON_BUILD_TESTS)
include(CTest)
add_subdirectory(test)
endif()

if (BUILD_TESTING AND NOT BOOST_SUPERPROJECT_VERSION)
add_subdirectory(bench)
if(BOOST_JSON_BUILD_EXAMPLES AND NOT BOOST_SUPERPROJECT_VERSION)
add_subdirectory(example)
endif()

if(BOOST_JSON_BUILD_BENCHMARKS AND NOT BOOST_SUPERPROJECT_VERSION)
add_subdirectory(bench)
endif()
10 changes: 10 additions & 0 deletions cmake/config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@PACKAGE_INIT@

set(BOOST_JSON_STANDALONE @BOOST_JSON_STANDALONE@)

if(NOT BOOST_JSON_STANDALONE)
include(CMakeFindDependencyMacro)
find_dependency(Boost REQUIRED COMPONENTS system)
endif()

include("${CMAKE_CURRENT_LIST_DIR}/boost_json-targets.cmake")
8 changes: 8 additions & 0 deletions cmake/toolchains/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON CACHE STRING "")
if(WIN32)
add_definitions(-D_WIN32_WINNT=0x0601 -D_CRT_SECURE_NO_WARNINGS)
endif()

# Project options.
set(BOOST_JSON_BUILD_BENCHMARKS ON CACHE STRING "")

# Detect Boost tree.
if(NOT DEFINED BOOST_JSON_IN_BOOST_TREE AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/../../../../Jamroot")
set(BOOST_JSON_IN_BOOST_TREE ON CACHE STRING "")
endif()
40 changes: 30 additions & 10 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#

file(GLOB_RECURSE BOOST_JSON_TESTS_FILES CONFIGURE_DEPENDS Jamfile *.cpp *.hpp)
list(FILTER BOOST_JSON_TESTS_FILES EXCLUDE REGEX "^${CMAKE_CURRENT_SOURCE_DIR}/cmake_install_test/.*$")

source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${BOOST_JSON_TESTS_FILES})
add_executable(tests ${BOOST_JSON_TESTS_FILES})
Expand All @@ -17,20 +18,39 @@ add_test(NAME json-tests COMMAND tests)

source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES limits.cpp main.cpp)
add_executable(limits limits.cpp main.cpp)
if(BOOST_JSON_STANDALONE)
target_include_directories(limits PRIVATE ../include)
target_compile_definitions(limits PRIVATE BOOST_JSON_STANDALONE)
else()
target_include_directories(limits PRIVATE ${BOOST_ROOT})
endif()
target_include_directories(limits PRIVATE .)
add_test(NAME json-limits COMMAND limits)
target_compile_definitions(limits PUBLIC

target_include_directories(limits PRIVATE ../include .)
target_compile_definitions(limits PRIVATE
BOOST_JSON_HEADER_ONLY=1
BOOST_JSON_DYN_LINK=1
BOOST_JSON_MAX_STRING_SIZE=1000
BOOST_JSON_MAX_OBJECT_SIZE=30
BOOST_JSON_MAX_ARRAY_SIZE=100
BOOST_JSON_MAX_STACK_SIZE=1024
BOOST_JSON_PARSER_BUFFER_SIZE=256
)

if(BOOST_JSON_STANDALONE)
target_compile_definitions(limits PRIVATE BOOST_JSON_STANDALONE)
target_compile_features(limits PRIVATE cxx_std_17)
elseif(BOOST_SUPERPROJECT_VERSION)
target_link_libraries(limits
PRIVATE
Boost::assert
Boost::config
Boost::container
Boost::core
Boost::exception
Boost::system
Boost::utility
)
elseif(BOOST_JSON_IN_BOOST_TREE)
target_include_directories(limits PRIVATE ${BOOST_ROOT})
target_link_directories(limits PRIVATE ${BOOST_ROOT}/stage/lib)
else()
target_link_libraries(limits
PRIVATE
Boost::system
)
endif()

add_test(NAME json-limits COMMAND limits)
18 changes: 18 additions & 0 deletions test/cmake_install_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2018 Peter Dimov
# Copyright 2018 Richard Hodges
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt

cmake_minimum_required(VERSION 3.5...3.16)

project(cmake_install_test LANGUAGES CXX)

find_package(boost_json REQUIRED)

add_executable(main main.cpp)
target_link_libraries(main Boost::json)

enable_testing()
add_test(NAME main COMMAND main)

add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
13 changes: 13 additions & 0 deletions test/cmake_install_test/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2018 Peter Dimov
// Copyright 2020 Richard Hodges
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt

#include <boost/json.hpp>
#include <cstdio>

int main()
{
const boost::json::value value = boost::json::parse("{ \"test\": true }");
std::puts(boost::json::to_string(value).c_str());
}

0 comments on commit e74f9bf

Please sign in to comment.