From bc95b55c351248ca10062ad1febdfbf43d11b9b5 Mon Sep 17 00:00:00 2001 From: Alexej Harm Date: Fri, 27 Dec 2019 05:42:26 +0100 Subject: [PATCH] Refactor CMake support: * Add VS CMake integration config * add cmake 3.10.0 support * fix compiler and linker flags * disable verbose build output * added cmake policy * Fix source groups * Group folder related settings * Add support for the boost superproject and cmake 3.16 * Remove library headers from executable projects * Fix boost superproject compatibility --- .gitignore | 19 ++-- CMakeLists.txt | 197 ++++++++++------------------------ README.md | 5 + bench/CMakeLists.txt | 39 ++----- cmake/toolchains/clang.cmake | 5 + cmake/toolchains/common.cmake | 18 ++++ cmake/toolchains/gcc.cmake | 5 + cmake/toolchains/msvc.cmake | 28 +++++ example/CMakeLists.txt | 14 ++- test/CMakeLists.txt | 52 ++------- 10 files changed, 154 insertions(+), 228 deletions(-) create mode 100644 cmake/toolchains/clang.cmake create mode 100644 cmake/toolchains/common.cmake create mode 100644 cmake/toolchains/gcc.cmake create mode 100644 cmake/toolchains/msvc.cmake diff --git a/.gitignore b/.gitignore index 65e0d05c..676fd1cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,13 @@ -bin -bin64 -*.*# +/bin +/bin64 temp -# Because of CMake and VS2017 -Win32/ -x64/ -out/ -.vs/ +# Emacs +*# + +# Vim +*~ + +# Visual Studio +/.vs +/out diff --git a/CMakeLists.txt b/CMakeLists.txt index b3238468..d0e383e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,148 +7,67 @@ # Official repository: https://github.com/vinniefalco/json # -cmake_minimum_required (VERSION 3.5.1) +cmake_minimum_required(VERSION 3.5...3.16) -if (POLICY CMP0074) - cmake_policy (SET CMP0074 NEW) +set(BOOST_JSON_VERSION 1) +if(BOOST_SUPERPROJECT_VERSION) + set(BOOST_JSON_VERSION ${BOOST_SUPERPROJECT_VERSION}) endif() -#------------------------------------------------------------------------------- +project(boost_json VERSION ${BOOST_JSON_VERSION} LANGUAGES CXX) -function (DoGroupSources curdir rootdir folder) - file (GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*) - foreach (child ${children}) - if (IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child}) - DoGroupSources (${curdir}/${child} ${rootdir} ${folder}) - elseif (${child} STREQUAL "CMakeLists.txt") - source_group("" FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child}) - else() - string (REGEX REPLACE ^${rootdir} ${folder} groupname ${curdir}) - string (REPLACE "/" "\\" groupname ${groupname}) - source_group (${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child}) - endif() - endforeach() -endfunction() - -function (GroupSources curdir folder) - DoGroupSources (${curdir} ${curdir} ${folder}) -endfunction() - -#------------------------------------------------------------------------------- -# -# JSON -# -#------------------------------------------------------------------------------- - -project (JSON VERSION 1) - -set_property (GLOBAL PROPERTY USE_FOLDERS ON) - -if (MSVC) - set (CMAKE_VERBOSE_MAKEFILE FALSE) - - add_definitions ( - -D_WIN32_WINNT=0x0601 - -D_CRT_SECURE_NO_WARNINGS - ) - - add_compile_options( - /permissive- # strict C++ - /W4 # enable all warnings - /MP # Multi-processor compilation - ) - - add_link_options( - /INCREMENTAL:NO - ) - - set (Boost_USE_STATIC_LIBS ON) - set (Boost_USE_STATIC_RUNTIME ON) - - set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") - set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ob2 /Oi /Ot /GL /MT") - set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi /Ot /MT") - - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO") - set (CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG") - - # for RelWithDebInfo builds, disable incremental linking - # since CMake sets it ON by default for that build type and it - # causes warnings - # - string (REPLACE "/INCREMENTAL" "/INCREMENTAL:NO" replacement_flags - ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}) - set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO ${replacement_flags}) - -else() - set (THREADS_PREFER_PTHREAD_FLAG ON) - find_package (Threads) - - set( CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wpedantic -Wno-unused-parameter") - - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wrange-loop-analysis") - endif () -endif() - -# Must come before Boost includes, otherwise the -# IDE sees the wrong file due to boost/ symlinks. -include_directories (include) - -#------------------------------------------------------------------------------- -# -# Boost -# -#------------------------------------------------------------------------------- - -get_filename_component (BOOST_ROOT ../../ ABSOLUTE) - -# VFALCO I want static but "b2 stage" builds a minimal set which excludes static -add_definitions (-DBOOST_ALL_STATIC_LINK=1) - -include_directories (${BOOST_ROOT}) - -link_directories(${BOOST_ROOT}/stage/lib) - -#------------------------------------------------------------------------------- - -if ("${VARIANT}" STREQUAL "coverage") - if (MSVC) - else() - set (CMAKE_BUILD_TYPE DEBUG) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2 --coverage") - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") - endif() - -elseif ("${VARIANT}" STREQUAL "ubasan") - if (MSVC) - else() - set (CMAKE_BUILD_TYPE RELWITHDEBINFO) - set (CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} -msse4.2 -funsigned-char -fno-omit-frame-pointer -fsanitize=address,undefined -fno-sanitize-recover=address,undefined -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/tools/blacklist.supp") - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address,undefined -fno-sanitize-recover=address,undefined") - endif() - -elseif ("${VARIANT}" STREQUAL "debug") - set (CMAKE_BUILD_TYPE DEBUG) - -elseif ("${VARIANT}" STREQUAL "release") - set (CMAKE_BUILD_TYPE RELEASE) - -endif() - -#------------------------------------------------------------------------------- -# -# Tests and examples -# - -file (GLOB_RECURSE PROJECT_FILES - ${PROJECT_SOURCE_DIR}/include/boost/json/*.hpp - ${PROJECT_SOURCE_DIR}/include/boost/json/*.ipp - ${PROJECT_SOURCE_DIR}/include/boost/json/*.natvis +file(GLOB_RECURSE BOOST_JSON_HEADERS CONFIGURE_DEPENDS + include/boost/*.hpp + include/boost/*.ipp + include/boost/*.natvis ) -add_subdirectory (bench) -add_subdirectory (example) -add_subdirectory (test) +set(BOOST_JSON_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/src/src.cpp +) + +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() + +add_library(boost_json ${BOOST_JSON_HEADERS} ${BOOST_JSON_SOURCES}) +add_library(Boost::json ALIAS boost_json) + +target_compile_features(boost_json PUBLIC cxx_constexpr) + +target_include_directories(boost_json PUBLIC include) + +target_compile_definitions(boost_json PUBLIC BOOST_JSON_NO_LIB=1) + +if(BUILD_SHARED_LIBS) + target_compile_definitions(boost_json PUBLIC BOOST_JSON_DYN_LINK=1) +else() + target_compile_definitions(boost_json PUBLIC BOOST_JSON_STATIC_LINK=1) +endif() + +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + if(${CMAKE_VERSION} VERSION_LESS 3.16) + message(FATAL_ERROR "Boost.JSON development requires CMake 3.16 or newer.") + endif() + + get_filename_component(BOOST_ROOT ../.. ABSOLUTE) + target_include_directories(boost_json PUBLIC ${BOOST_ROOT}) + target_link_directories(boost_json PUBLIC ${BOOST_ROOT}/stage/lib) + + add_subdirectory(bench) + add_subdirectory(example) + add_subdirectory(test) +else() + target_link_libraries(boost_json + PUBLIC + Boost::assert + Boost::config + Boost::core + Boost::exception + Boost::system + Boost::utility + ) +endif() diff --git a/README.md b/README.md index 3a5a47a3..1b191eef 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,11 @@ The design of the library also achieves these goals: * Security-aware treatment of untrusted inputs * Fast compilation performance +## CMake + + cmake -G "Visual Studio 16 2019" -A Win32 -B bin -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/msvc.cmake + cmake -G "Visual Studio 16 2019" -A x64 -B bin64 -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/msvc.cmake + ## License Distributed under the Boost Software License, Version 1.0. diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt index 64cfeb8b..0ce124a3 100644 --- a/bench/CMakeLists.txt +++ b/bench/CMakeLists.txt @@ -7,38 +7,17 @@ # Official repository: https://github.com/vinniefalco/json # -source_group (json FILES ${PROJECT_SOURCE_DIR}/include/boost/json.hpp) -source_group (json FILES ${PROJECT_SOURCE_DIR}/include/boost/pilfer.hpp) -source_group (TREE ${PROJECT_SOURCE_DIR}/include/boost/json PREFIX json FILES ${PROJECT_FILES}) - -GroupSources(bench "/") - -# Disable auto-linking -add_definitions(-DBOOST_ALL_NO_LIB=1) - -include_directories(../test) - -if (MSVC) - if (CMAKE_BUILD_TYPE EQUAL "Debug") - else() - add_compile_options( - /GL # Whole program optimization - /Ob2 # inline any suitable - ) - - add_link_options( - /LTCG # Link Time Code Generation - ) - endif() -endif() - -add_executable (bench - ${PROJECT_FILES} - ${PROJECT_SOURCE_DIR}/include/boost/json.hpp - ${PROJECT_SOURCE_DIR}/include/boost/pilfer.hpp - ${PROJECT_SOURCE_DIR}/src/src.cpp +source_group("" FILES Jamfile bench.cpp ) +add_executable(bench + Jamfile + bench.cpp +) + +target_include_directories(bench PRIVATE ../test) +target_link_libraries(bench PRIVATE boost_json) + add_test(json-tests json-tests) diff --git a/cmake/toolchains/clang.cmake b/cmake/toolchains/clang.cmake new file mode 100644 index 00000000..72dfd3e9 --- /dev/null +++ b/cmake/toolchains/clang.cmake @@ -0,0 +1,5 @@ +# Include gcc options. +include(${CMAKE_CURRENT_LIST_DIR}/gcc.cmake) + +# Compiler options. +add_compile_options(-Wrange-loop-analysis) diff --git a/cmake/toolchains/common.cmake b/cmake/toolchains/common.cmake new file mode 100644 index 00000000..313bbddf --- /dev/null +++ b/cmake/toolchains/common.cmake @@ -0,0 +1,18 @@ +# C++ standard. +set(CMAKE_CXX_STANDARD 11 CACHE STRING "") +set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE STRING "") +set(CMAKE_CXX_EXTENSIONS OFF CACHE STRING "") + +# Static library linkage. +set(BUILD_SHARED_LIBS OFF CACHE STRING "") +add_definitions(-DBOOST_ALL_STATIC_LINK=1) + +# Interprocedural optimization. +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON CACHE STRING "") +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL ON CACHE STRING "") +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON CACHE STRING "") + +# Compiler definitions. +if(WIN32) + add_definitions(-D_WIN32_WINNT=0x0601 -D_CRT_SECURE_NO_WARNINGS) +endif() diff --git a/cmake/toolchains/gcc.cmake b/cmake/toolchains/gcc.cmake new file mode 100644 index 00000000..b6a8e1d0 --- /dev/null +++ b/cmake/toolchains/gcc.cmake @@ -0,0 +1,5 @@ +# Include common options. +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) + +# Compiler options. +add_compile_options(-Wall -Wextra -Wpedantic -Wno-unused-parameter) diff --git a/cmake/toolchains/msvc.cmake b/cmake/toolchains/msvc.cmake new file mode 100644 index 00000000..5e7bc91a --- /dev/null +++ b/cmake/toolchains/msvc.cmake @@ -0,0 +1,28 @@ +# Include common options. +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) + +# Static runtime linkage. +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" CACHE STRING "") + +# Compiler options. +add_compile_options( + /permissive- # strict C++ + /W4 # enable all warnings + /MP # multi-processor compilation +) + +# Linker options. +add_link_options( +) + +# Disable logos. +foreach(lang C CXX ASM_MASM RC) + set(CMAKE_${lang}_FLAGS_INIT "/nologo") +endforeach() +foreach(type EXE SHARED MODULE) + set(CMAKE_${type}_LINKER_FLAGS_INIT "/nologo") +endforeach() + +# Silence Visual Studio CMake integration warnings. +set(SILENCE_VS_DEFINITIONS ${CMAKE_TOOLCHAIN_FILE} ${CMAKE_C_COMPILER}) +set(SILENCE_VS_DEFINITIONS) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 030bf7de..3c00f636 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -7,18 +7,22 @@ # Official repository: https://github.com/vinniefalco/json # -GroupSources(example "/") +source_group("" FILES + file.hpp + pretty.cpp + validate.cpp +) -add_executable (pretty - ${PROJECT_SOURCE_DIR}/src/src.cpp +add_executable(pretty file.hpp pretty.cpp ) set_property(TARGET pretty PROPERTY FOLDER "example") +target_link_libraries(pretty PRIVATE boost_json) -add_executable (validate - ${PROJECT_SOURCE_DIR}/src/src.cpp +add_executable(validate file.hpp validate.cpp ) set_property(TARGET validate PROPERTY FOLDER "example") +target_link_libraries(validate PRIVATE boost_json) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6ae00582..4b03e414 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,52 +7,12 @@ # Official repository: https://github.com/vinniefalco/json # -source_group (boost FILES ${PROJECT_SOURCE_DIR}/include/boost/json.hpp) -source_group (boost FILES ${PROJECT_SOURCE_DIR}/include/boost/pilfer.hpp) -source_group (TREE ${PROJECT_SOURCE_DIR}/include/boost/json PREFIX json FILES ${PROJECT_FILES}) +file(GLOB_RECURSE BOOST_JSON_TESTS_FILES CONFIGURE_DEPENDS Jamfile *.cpp *.hpp) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${BOOST_JSON_TESTS_FILES}) -GroupSources(test "/") +add_executable(tests ${BOOST_JSON_TESTS_FILES}) -add_definitions(-DBOOST_JSON_HEADER_ONLY=1) +target_include_directories(tests PRIVATE .) +target_link_libraries(tests PRIVATE boost_json) -include_directories(.) - -add_executable (json-tests - ${PROJECT_FILES} - ${PROJECT_SOURCE_DIR}/include/boost/json.hpp - ${PROJECT_SOURCE_DIR}/include/boost/pilfer.hpp - ${PROJECT_SOURCE_DIR}/include/boost/json/json.natvis - ${PROJECT_SOURCE_DIR}/src/src.cpp - Jamfile - test.hpp - test_suite.hpp - parse-vectors.hpp - main.cpp - _detail_number.cpp - array.cpp - basic_parser.cpp - error.cpp - json.cpp - kind.cpp - limits.cpp - number_cast.cpp - object.cpp - parser.cpp - pool.cpp - serializer.cpp - snippets.cpp - storage.cpp - storage_ptr.cpp - string.cpp - to_value.cpp - traits.cpp - value.cpp - value_cast.cpp - value_ref.cpp - ryu/d2s_intrinsics_test.cpp - ryu/d2s_table_test.cpp - ryu/d2s_test.cpp - ryu/gtest.hpp -) - -add_test(json-tests json-tests) +add_test(json-tests tests)