Skip to content

Better support for modern CMake #1374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 19 commits into from
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ compile_commands.json
*.a

# eclipse project files
.idea/
.project
.cproject
/.settings/
Expand All @@ -55,3 +56,4 @@ compile_commands.json

# temps
/version
cmake-build-*/
41 changes: 5 additions & 36 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ foreach(pold "") # Currently Empty
endif()
endforeach()

# Build the library with C++11 standard support, independent from other including
# software which may use a different CXX_STANDARD or CMAKE_CXX_STANDARD.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Ensure that CMAKE_BUILD_TYPE has a value specified for single configuration generators.
if(NOT DEFINED CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Release CACHE STRING
Expand Down Expand Up @@ -78,6 +72,9 @@ project(jsoncpp
message(STATUS "JsonCpp Version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
set(PROJECT_SOVERSION 25)

# Defines the project root to be used throughout all scripts.
SET(JSONCPP_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})

include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInSourceBuilds.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInBuildInstalls.cmake)

Expand All @@ -89,18 +86,12 @@ option(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON)
option(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" ON)
option(JSONCPP_WITH_EXAMPLE "Compile JsonCpp example" OFF)
option(JSONCPP_STATIC_WINDOWS_RUNTIME "Use static (MT/MTd) Windows runtime" OFF)
option(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." ON)
option(BUILD_STATIC_LIBS "Build jsoncpp_lib as a static library." ON)
option(BUILD_OBJECT_LIBS "Build jsoncpp_lib as a object library." ON)

option(JSONCPP_BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF)

# Adhere to GNU filesystem layout conventions
include(GNUInstallDirs)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Archive output dir.")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Library output dir.")
set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "PDB (MSVC debug symbol)output dir.")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Executable/dll output dir.")

set(JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL")

configure_file("${PROJECT_SOURCE_DIR}/version.in"
Expand All @@ -120,9 +111,6 @@ macro(use_compilation_warning_as_error)
endif()
endmacro()

# Include our configuration header
include_directories(${jsoncpp_SOURCE_DIR}/include)

if(MSVC)
# Only enabled in debug because some old versions of VS STL generate
# unreachable code warning when compiled in release configuration.
Expand Down Expand Up @@ -179,22 +167,6 @@ if(JSONCPP_WITH_PKGCONFIG_SUPPORT)
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endif()

if(JSONCPP_WITH_CMAKE_PACKAGE)
include(CMakePackageConfigHelpers)
install(EXPORT jsoncpp
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp
FILE jsoncpp-targets.cmake)
configure_package_config_file(jsoncppConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp)

write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfig.cmake
${CMAKE_CURRENT_SOURCE_DIR}/jsoncpp-namespaced-targets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp)
endif()

if(JSONCPP_WITH_TESTS)
enable_testing()
Expand All @@ -204,9 +176,6 @@ endif()
# Build the different applications
add_subdirectory(src)

#install the includes
add_subdirectory(include)

#install the example
if(JSONCPP_WITH_EXAMPLE)
add_subdirectory(example)
Expand Down
29 changes: 4 additions & 25 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,27 +1,6 @@
#vim: et ts =4 sts = 4 sw = 4 tw = 0
set(EXAMPLES
readFromString
readFromStream
stringWrite
streamWrite
)
add_definitions(-D_GLIBCXX_USE_CXX11_ABI)

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-Wall -Wextra)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_definitions(
-D_SCL_SECURE_NO_WARNINGS
-D_CRT_SECURE_NO_WARNINGS
-D_WIN32_WINNT=0x601
-D_WINSOCK_DEPRECATED_NO_WARNINGS
)
endif()

foreach(example ${EXAMPLES})
add_executable(${example} ${example}/${example}.cpp)
target_include_directories(${example} PUBLIC ${CMAKE_SOURCE_DIR}/include)
target_link_libraries(${example} jsoncpp_lib)
endforeach()

add_custom_target(examples ALL DEPENDS ${EXAMPLES})
ADD_SUBDIRECTORY(readFromStream/)
ADD_SUBDIRECTORY(readFromString/)
ADD_SUBDIRECTORY(streamWrite/)
ADD_SUBDIRECTORY(stringWrite/)
2 changes: 2 additions & 0 deletions example/readFromStream/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ADD_EXECUTABLE(readFromStream readFromStream.cpp)
TARGET_LINK_LIBRARIES(readFromStream PRIVATE jsoncpp::framework)
2 changes: 2 additions & 0 deletions example/readFromString/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ADD_EXECUTABLE(readFromString readFromString.cpp)
TARGET_LINK_LIBRARIES(readFromString PRIVATE jsoncpp::framework)
2 changes: 2 additions & 0 deletions example/streamWrite/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ADD_EXECUTABLE(streamWrite streamWrite.cpp)
TARGET_LINK_LIBRARIES(streamWrite PRIVATE jsoncpp::framework)
2 changes: 2 additions & 0 deletions example/stringWrite/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ADD_EXECUTABLE(stringWrite stringWrite.cpp)
TARGET_LINK_LIBRARIES(stringWrite PRIVATE jsoncpp::framework)
5 changes: 1 addition & 4 deletions include/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
file(GLOB INCLUDE_FILES "json/*.h")
install(FILES
${INCLUDE_FILES}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/json)


44 changes: 13 additions & 31 deletions src/jsontestrunner/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,51 +1,33 @@
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0)
# The new Python3 module is much more robust than the previous PythonInterp
find_package(Python3 COMPONENTS Interpreter)
# Set variables for backwards compatibility with cmake < 3.12.0
set(PYTHONINTERP_FOUND ${Python3_Interpreter_FOUND})
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
else()
set(Python_ADDITIONAL_VERSIONS 3.8)
find_package(PythonInterp 3)
endif()

add_executable(jsontestrunner_exe
main.cpp
)
# The new Python3 module is much more robust than the previous PythonInterp
FIND_PACKAGE(Python3 COMPONENTS Interpreter)
# Set variables for backwards compatibility with cmake < 3.12.0
SET(PYTHONINTERP_FOUND ${Python3_Interpreter_FOUND})
SET(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})

if(BUILD_SHARED_LIBS)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0)
add_compile_definitions( JSON_DLL )
else()
add_definitions(-DJSON_DLL)
endif()
target_link_libraries(jsontestrunner_exe jsoncpp_lib)
else()
target_link_libraries(jsontestrunner_exe jsoncpp_static)
endif()
ADD_EXECUTABLE(jsontestrunner_exe main.cpp)
TARGET_LINK_LIBRARIES(jsontestrunner_exe PRIVATE jsoncpp::framework)

set_target_properties(jsontestrunner_exe PROPERTIES OUTPUT_NAME jsontestrunner_exe)

if(PYTHONINTERP_FOUND)
# Run end to end parser/writer tests
set(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../test)
set(RUNJSONTESTS_PATH ${TEST_DIR}/runjsontests.py)
set(RUNJSONTESTS_PATH ${JSONCPP_ROOT_DIR}/test/runjsontests.py)

# Run unit tests in post-build
# (default cmake workflow hides away the test result into a file, resulting in poor dev workflow?!?)
add_custom_target(jsoncpp_readerwriter_tests
"${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $<TARGET_FILE:jsontestrunner_exe> "${TEST_DIR}/data"
"${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $<TARGET_FILE:jsontestrunner_exe> "${JSONCPP_ROOT_DIR}/test/data"
DEPENDS jsontestrunner_exe jsoncpp_test
)
add_custom_target(jsoncpp_check DEPENDS jsoncpp_readerwriter_tests)

## Create tests for dashboard submission, allows easy review of CI results https://my.cdash.org/index.php?project=jsoncpp
add_test(NAME jsoncpp_readerwriter
COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $<TARGET_FILE:jsontestrunner_exe> "${TEST_DIR}/data"
WORKING_DIRECTORY "${TEST_DIR}/data"
COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $<TARGET_FILE:jsontestrunner_exe> "${JSONCPP_ROOT_DIR}/test/data"
WORKING_DIRECTORY "${JSONCPP_ROOT_DIR}/test/data"
)
add_test(NAME jsoncpp_readerwriter_json_checker
COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" --with-json-checker $<TARGET_FILE:jsontestrunner_exe> "${TEST_DIR}/data"
WORKING_DIRECTORY "${TEST_DIR}/data"
COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" --with-json-checker $<TARGET_FILE:jsontestrunner_exe> "${JSONCPP_ROOT_DIR}/test/data"
WORKING_DIRECTORY "${JSONCPP_ROOT_DIR}/test/data"
)
endif()
144 changes: 25 additions & 119 deletions src/lib_json/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,41 +25,11 @@ if(NOT (HAVE_CLOCALE AND HAVE_LCONV_SIZE AND HAVE_DECIMAL_POINT AND HAVE_LOCALEC
endif()
endif()

set(JSONCPP_INCLUDE_DIR ../../include)

set(PUBLIC_HEADERS
${JSONCPP_INCLUDE_DIR}/json/config.h
${JSONCPP_INCLUDE_DIR}/json/forwards.h
${JSONCPP_INCLUDE_DIR}/json/json_features.h
${JSONCPP_INCLUDE_DIR}/json/value.h
${JSONCPP_INCLUDE_DIR}/json/reader.h
${JSONCPP_INCLUDE_DIR}/json/version.h
${JSONCPP_INCLUDE_DIR}/json/writer.h
${JSONCPP_INCLUDE_DIR}/json/assertions.h
)

source_group("Public API" FILES ${PUBLIC_HEADERS})

set(JSONCPP_SOURCES
json_tool.h
json_reader.cpp
json_valueiterator.inl
json_value.cpp
json_writer.cpp
)

# Install instructions for this target
if(JSONCPP_WITH_CMAKE_PACKAGE)
set(INSTALL_EXPORT EXPORT jsoncpp)
else()
set(INSTALL_EXPORT)
endif()

# Specify compiler features required when compiling a given target.
# See https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html#prop_gbl:CMAKE_CXX_KNOWN_FEATURES
# for complete list of features available
list(APPEND REQUIRED_FEATURES
cxx_std_11 # Compiler mode is aware of C++ 11.
#MSVC 1900 cxx_alignas # Alignment control alignas, as defined in N2341.
#MSVC 1900 cxx_alignof # Alignment control alignof, as defined in N2341.
#MSVC 1900 cxx_attributes # Generic attributes, as defined in N2761.
Expand Down Expand Up @@ -106,103 +76,39 @@ list(APPEND REQUIRED_FEATURES
)


if(BUILD_SHARED_LIBS)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0)
add_compile_definitions(JSON_DLL_BUILD)
else()
add_definitions(-DJSON_DLL_BUILD)
endif()

set(SHARED_LIB ${PROJECT_NAME}_lib)
add_library(${SHARED_LIB} SHARED ${PUBLIC_HEADERS} ${JSONCPP_SOURCES})
set_target_properties(${SHARED_LIB} PROPERTIES
OUTPUT_NAME jsoncpp
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_SOVERSION}
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)

# Set library's runtime search path on OSX
if(APPLE)
set_target_properties(${SHARED_LIB} PROPERTIES INSTALL_RPATH "@loader_path/.")
endif()

target_compile_features(${SHARED_LIB} PUBLIC ${REQUIRED_FEATURES})

target_include_directories(${SHARED_LIB} PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include/json>
)

list(APPEND CMAKE_TARGETS ${SHARED_LIB})
endif()

if(BUILD_STATIC_LIBS)
set(STATIC_LIB ${PROJECT_NAME}_static)
add_library(${STATIC_LIB} STATIC ${PUBLIC_HEADERS} ${JSONCPP_SOURCES})

# avoid name clashes on windows as the shared import lib is also named jsoncpp.lib
if(NOT DEFINED STATIC_SUFFIX AND BUILD_SHARED_LIBS)
if (MSVC)
set(STATIC_SUFFIX "_static")
else()
set(STATIC_SUFFIX "")
endif()
endif()

set_target_properties(${STATIC_LIB} PROPERTIES
OUTPUT_NAME jsoncpp${STATIC_SUFFIX}
VERSION ${PROJECT_VERSION}
)

# Set library's runtime search path on OSX
if(APPLE)
set_target_properties(${STATIC_LIB} PROPERTIES INSTALL_RPATH "@loader_path/.")
endif()
ADD_LIBRARY(jsoncpp.framework.object OBJECT
json_reader.cpp
json_value.cpp
json_writer.cpp
)

target_compile_features(${STATIC_LIB} PUBLIC ${REQUIRED_FEATURES})
SET_TARGET_PROPERTIES(jsoncpp.framework.object PROPERTIES CXX_STANDARD 11)
SET_TARGET_PROPERTIES(jsoncpp.framework.object PROPERTIES VERSION ${PROJECT_VERSION})
SET_TARGET_PROPERTIES(jsoncpp.framework.object PROPERTIES SOVERSION ${PROJECT_SOVERSION})

target_include_directories(${STATIC_LIB} PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include/json>
)
TARGET_COMPILE_FEATURES(jsoncpp.framework.object PUBLIC ${REQUIRED_FEATURES})
TARGET_INCLUDE_DIRECTORIES(jsoncpp.framework.object PUBLIC $<BUILD_INTERFACE:${JSONCPP_ROOT_DIR}/include>)

list(APPEND CMAKE_TARGETS ${STATIC_LIB})
endif()

if(BUILD_OBJECT_LIBS)
set(OBJECT_LIB ${PROJECT_NAME}_object)
add_library(${OBJECT_LIB} OBJECT ${PUBLIC_HEADERS} ${JSONCPP_SOURCES})
IF (JSONCPP_BUILD_SHARED_LIBS)

set_target_properties(${OBJECT_LIB} PROPERTIES
OUTPUT_NAME jsoncpp
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_SOVERSION}
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
# CMake link shared library on Windows
# Ref: https://stackoverflow.com/a/41618677
SET(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)

# Set library's runtime search path on OSX
if(APPLE)
set_target_properties(${OBJECT_LIB} PROPERTIES INSTALL_RPATH "@loader_path/.")
endif()
ADD_LIBRARY(jsoncpp.framework SHARED $<TARGET_OBJECTS:jsoncpp.framework.object>)
TARGET_COMPILE_DEFINITIONS(jsoncpp.framework PUBLIC JSON_DLL_BUILD)

target_compile_features(${OBJECT_LIB} PUBLIC ${REQUIRED_FEATURES})
ELSE ()

target_include_directories(${OBJECT_LIB} PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include/json>
)
ADD_LIBRARY(jsoncpp.framework STATIC $<TARGET_OBJECTS:jsoncpp.framework.object>)

list(APPEND CMAKE_TARGETS ${OBJECT_LIB})
endif()
ENDIF ()

install(TARGETS ${CMAKE_TARGETS} ${INSTALL_EXPORT}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
OBJECTS DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
ADD_LIBRARY(jsoncpp::framework ALIAS jsoncpp.framework)
SET_TARGET_PROPERTIES(jsoncpp.framework PROPERTIES CXX_STANDARD 11)
SET_TARGET_PROPERTIES(jsoncpp.framework PROPERTIES VERSION ${PROJECT_VERSION})
SET_TARGET_PROPERTIES(jsoncpp.framework PROPERTIES SOVERSION ${PROJECT_SOVERSION})

TARGET_COMPILE_FEATURES(jsoncpp.framework PUBLIC ${REQUIRED_FEATURES})
TARGET_INCLUDE_DIRECTORIES(jsoncpp.framework PUBLIC $<BUILD_INTERFACE:${JSONCPP_ROOT_DIR}/include>)
Loading