Fix string_view ABI mismatch between library and consumers (#1661)
The library was forced to build with CMAKE_CXX_STANDARD 11, so
JSONCPP_HAS_STRING_VIEW was never defined at compile time. Consumers
building with C++17 would see the string_view APIs in the header but
fail to link them.
Fix:
- Remove the global CMAKE_CXX_STANDARD 11 override; the existing
target_compile_features(cxx_std_11) already enforces the minimum.
- Detect string_view support at configure time with
check_cxx_source_compiles and export JSONCPP_HAS_STRING_VIEW as a
PUBLIC compile definition on all library targets, so consumers
always see the same value the library was built with.
- Guard the __cplusplus fallback in value.h so it does not override
the CMake-set define.
Fixes #1595
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cfd1a4e..bc8575f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,12 +40,6 @@
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
diff --git a/include/json/value.h b/include/json/value.h
index a7a39a1..f32f456 100644
--- a/include/json/value.h
+++ b/include/json/value.h
@@ -39,9 +39,11 @@
#endif
#endif
+#ifndef JSONCPP_HAS_STRING_VIEW
#if __cplusplus >= 201703L
#define JSONCPP_HAS_STRING_VIEW 1
#endif
+#endif
#include <array>
#include <exception>
diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt
index 9658941..03e9335 100644
--- a/src/lib_json/CMakeLists.txt
+++ b/src/lib_json/CMakeLists.txt
@@ -7,6 +7,7 @@
include(CheckTypeSize)
include(CheckStructHasMember)
include(CheckCXXSymbolExists)
+include(CheckCXXSourceCompiles)
check_include_file_cxx(clocale HAVE_CLOCALE)
check_cxx_symbol_exists(localeconv clocale HAVE_LOCALECONV)
@@ -25,6 +26,11 @@
endif()
endif()
+check_cxx_source_compiles(
+ "#include <string_view>
+ int main() { std::string_view sv; return 0; }"
+ JSONCPP_HAS_STRING_VIEW)
+
set(JSONCPP_INCLUDE_DIR ../../include)
set(PUBLIC_HEADERS
@@ -125,6 +131,10 @@
target_compile_features(${SHARED_LIB} PUBLIC ${REQUIRED_FEATURES})
+ if(JSONCPP_HAS_STRING_VIEW)
+ target_compile_definitions(${SHARED_LIB} PUBLIC JSONCPP_HAS_STRING_VIEW=1)
+ endif()
+
target_include_directories(${SHARED_LIB} PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}>
@@ -158,6 +168,10 @@
target_compile_features(${STATIC_LIB} PUBLIC ${REQUIRED_FEATURES})
+ if(JSONCPP_HAS_STRING_VIEW)
+ target_compile_definitions(${STATIC_LIB} PUBLIC JSONCPP_HAS_STRING_VIEW=1)
+ endif()
+
target_include_directories(${STATIC_LIB} PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}>
@@ -184,6 +198,10 @@
target_compile_features(${OBJECT_LIB} PUBLIC ${REQUIRED_FEATURES})
+ if(JSONCPP_HAS_STRING_VIEW)
+ target_compile_definitions(${OBJECT_LIB} PUBLIC JSONCPP_HAS_STRING_VIEW=1)
+ endif()
+
target_include_directories(${OBJECT_LIB} PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}>