2012-06-04 01:27:48 +08:00
# Notes:
2013-03-15 04:18:21 +08:00
#
2012-06-04 01:27:48 +08:00
# Author: Paul Harris, June 2012
2019-09-21 01:35:56 +08:00
# Additions: Joakim Soderberg, February 2013
2013-03-15 04:18:21 +08:00
#
# Supports: building static/shared, release/debug/etc, can also build html docs
2013-02-28 07:16:32 +08:00
# and some of the tests.
2013-03-15 04:18:21 +08:00
# Note that its designed for out-of-tree builds, so it will not pollute your
2013-02-28 07:16:32 +08:00
# source tree.
2013-03-15 04:18:21 +08:00
#
# TODO 1: Finish implementing tests. api tests are working, but the valgrind
2013-02-28 07:16:32 +08:00
# variants are not flagging problems.
2013-03-15 04:18:21 +08:00
#
2012-06-04 01:27:48 +08:00
# TODO 2: There is a check_exports script that would try and incorporate.
2013-03-15 04:18:21 +08:00
#
# TODO 3: Consolidate version numbers, currently the version number is written
# into: * cmake (here) * autotools (the configure) * source code header files.
2013-02-28 07:16:32 +08:00
# Should not be written directly into header files, autotools/cmake can do
# that job.
2013-03-15 04:18:21 +08:00
#
2012-06-04 01:27:48 +08:00
# Brief intro on how to use cmake:
# > mkdir build (somewhere - we do out-of-tree builds)
2013-02-28 07:16:32 +08:00
# > use cmake, ccmake, or cmake-gui to configure the project. for linux, you
# can only choose one variant: release,debug,etc... and static or shared.
2012-06-04 01:27:48 +08:00
# >> example:
# >> cd build
# >> ccmake -i ../path_to_jansson_dir
2013-03-15 04:18:21 +08:00
# >> inside, configure your options. press C until there are no lines
2013-02-28 07:16:32 +08:00
# with * next to them.
2013-03-15 04:18:21 +08:00
# >> note, I like to configure the 'install' path to ../install, so I get
2013-02-28 07:16:32 +08:00
# self-contained clean installs I can point other projects to.
2012-06-04 01:27:48 +08:00
# >> press G to 'generate' the project files.
# >> make (to build the project)
# >> make install
# >> make test (to run the tests, if you enabled them)
2013-03-15 04:18:21 +08:00
#
2012-06-04 01:27:48 +08:00
# Brief description on how it works:
2019-09-21 01:35:56 +08:00
# There is a small hierarchy of CMakeLists.txt files which define how the
2013-02-28 07:16:32 +08:00
# project is built.
2013-03-15 04:18:21 +08:00
# Header file detection etc is done, and the results are written into config.h
# and jansson_config.h, which are generated from the corresponding
2013-02-28 07:16:32 +08:00
# config.h.cmake and jansson_config.h.cmake template files.
2013-03-15 04:18:21 +08:00
# The generated header files end up in the build directory - not in
2013-02-28 07:16:32 +08:00
# the source directory.
2012-06-04 01:27:48 +08:00
# The rest is down to the usual make process.
2018-03-11 21:34:45 +08:00
cmake_minimum_required ( VERSION 3.1 )
project ( jansson C )
2012-06-04 01:27:48 +08:00
# Options
2014-01-10 23:50:33 +08:00
option ( JANSSON_BUILD_SHARED_LIBS "Build shared libraries." OFF )
2014-02-11 20:49:15 +08:00
option ( USE_URANDOM "Use /dev/urandom to seed the hash function." ON )
option ( USE_WINDOWS_CRYPTOAPI "Use CryptGenRandom to seed the hash function." ON )
2012-06-04 01:27:48 +08:00
2013-06-25 23:36:11 +08:00
if ( MSVC )
2013-06-21 01:00:40 +08:00
# This option must match the settings used in your program, in particular if you
# are linking statically
2014-01-10 23:50:33 +08:00
option ( JANSSON_STATIC_CRT "Link the static CRT libraries" OFF )
2013-06-25 23:36:11 +08:00
endif ( )
2013-06-21 01:00:40 +08:00
2015-01-13 23:17:48 +08:00
option ( JANSSON_EXAMPLES "Compile example applications" ON )
2014-12-11 05:30:33 +08:00
if ( UNIX )
option ( JANSSON_COVERAGE "(GCC Only! Requires gcov/lcov to be installed). Include target for doing coverage analysis for the test suite. Note that -DCMAKE_BUILD_TYPE=Debug must be set" OFF )
option ( JANSSON_COVERALLS "Generate coverage info for Coveralls" OFF )
option ( JANSSON_COVERALLS_UPLOAD "Upload coverage info to Coveralls (Only works via Travis)" ON )
endif ( )
2013-02-28 01:54:26 +08:00
# Set some nicer output dirs.
2018-03-11 22:11:09 +08:00
set ( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ CMAKE_CURRENT_BINARY_DIR } /bin )
set ( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ CMAKE_CURRENT_BINARY_DIR } /lib )
set ( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${ CMAKE_CURRENT_BINARY_DIR } /lib )
set ( JANSSON_TEMP_DIR ${ CMAKE_CURRENT_BINARY_DIR } /tmp )
2013-02-28 01:54:26 +08:00
2013-06-02 17:20:25 +08:00
# Give the debug version a different postfix for windows,
# so both the debug and release version can be built in the
# same build-tree on Windows (MSVC).
2018-03-11 22:37:15 +08:00
if ( WIN32 AND NOT CMAKE_DEBUG_POSTFIX )
2014-01-10 23:50:33 +08:00
set ( CMAKE_DEBUG_POSTFIX "_d" )
2018-03-11 22:39:49 +08:00
endif ( )
2013-06-02 17:20:25 +08:00
2012-06-04 01:27:48 +08:00
# This is how I thought it should go
# set (JANSSON_VERSION "2.3.1")
# set (JANSSON_SOVERSION 2)
2020-05-08 02:38:59 +08:00
set ( JANSSON_DISPLAY_VERSION "2.13.1" )
2013-05-06 20:34:52 +08:00
2012-06-04 01:27:48 +08:00
# This is what is required to match the same numbers as automake's
2020-05-08 02:38:59 +08:00
set ( JANSSON_VERSION "4.13.0" )
2014-01-10 23:50:33 +08:00
set ( JANSSON_SOVERSION 4 )
2012-06-04 01:27:48 +08:00
# for CheckFunctionKeywords
2013-02-28 07:16:32 +08:00
set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" )
2012-06-04 01:27:48 +08:00
2014-02-11 20:49:15 +08:00
include ( CheckCSourceCompiles )
2012-06-04 01:27:48 +08:00
include ( CheckFunctionExists )
include ( CheckFunctionKeywords )
include ( CheckIncludeFiles )
include ( CheckTypeSize )
2019-09-21 01:35:56 +08:00
# suppress format-truncation warning
2019-08-09 15:41:57 +08:00
include ( CheckCCompilerFlag )
check_c_compiler_flag ( -Wno-format-truncation HAS_NO_FORMAT_TRUNCATION )
if ( HAS_NO_FORMAT_TRUNCATION )
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format-truncation" )
endif ( )
build: Add a symbol version to all exported symbols for glibc
The --default-symver linker option attaches a default version definition
(the SONAME) to every exported symbol. It is supported since at least
GNU binutils 2.22 in 2011 (older versions not tested).
With this version definition, newly-linked binaries that depend on the
jansson shared library will refer to its symbols in a versioned form,
preventing their references from being resolved to a symbol of the same
name exported by json-c or json-glib if those libraries appear in
dependency search order before jansson, which will usually result in
a crash. This is necessary because ELF symbol resolution normally uses
a single flat namespace, not a tree like Windows symbol resolution.
At least one symbol (json_object_iter_next()) is exported by all three
JSON libraries.
Linking with -Bsymbolic is not enough to have this effect in all cases,
because -Bsymbolic only affects symbol lookup within a shared object,
for example when parse_json() calls json_decref(). It does not affect
calls from external code into jansson, unless jansson was statically
linked into the external caller.
This change will also not prevent code that depends on json-c or
json-glib from finding jansson's symbols and crashing; to prevent
that, a corresponding change in json-c or json-glib would be needed.
Adding a symbol-version is a backwards-compatible change, but once
added, removing or changing the symbol-version would be an incompatible
change that requires a SONAME bump.
Resolves: https://github.com/akheron/jansson/issues/523
(when combined with an equivalent change to json-c).
Signed-off-by: Simon McVittie <smcv@collabora.com>
2020-06-30 01:28:38 +08:00
include ( CheckSymbolExists )
check_symbol_exists ( "__GLIBC__" "stdlib.h" LIBC_IS_GLIBC )
2013-02-28 01:54:26 +08:00
if ( MSVC )
2013-06-21 01:00:40 +08:00
# Turn off Microsofts "security" warnings.
2013-02-28 01:54:26 +08:00
add_definitions ( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo" )
2018-03-11 21:34:45 +08:00
2014-10-13 19:04:04 +08:00
if ( JANSSON_STATIC_CRT )
2014-10-13 19:06:02 +08:00
set ( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT" )
set ( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd" )
2013-06-21 01:00:40 +08:00
endif ( )
2013-04-18 17:25:17 +08:00
endif ( )
2014-12-11 05:30:33 +08:00
message ( "C compiler: ${CMAKE_C_COMPILER_ID}" )
# Coverage only works with GCC for a debug build.
if ( JANSSON_COVERALLS )
set ( JANSSON_COVERAGE ON )
endif ( )
if ( JANSSON_COVERAGE )
include ( CodeCoverage )
include ( Coveralls )
# This adds coverage arguments to gcc/clang.
coveralls_turn_on_coverage ( )
endif ( )
2014-01-14 17:16:39 +08:00
check_include_files ( endian.h HAVE_ENDIAN_H )
check_include_files ( fcntl.h HAVE_FCNTL_H )
check_include_files ( sched.h HAVE_SCHED_H )
check_include_files ( unistd.h HAVE_UNISTD_H )
check_include_files ( sys/param.h HAVE_SYS_PARAM_H )
check_include_files ( sys/stat.h HAVE_SYS_STAT_H )
check_include_files ( sys/time.h HAVE_SYS_TIME_H )
2017-11-07 16:32:14 +08:00
check_include_files ( sys/types.h HAVE_SYS_TYPES_H )
2014-01-14 17:16:39 +08:00
check_function_exists ( close HAVE_CLOSE )
check_function_exists ( getpid HAVE_GETPID )
check_function_exists ( gettimeofday HAVE_GETTIMEOFDAY )
check_function_exists ( open HAVE_OPEN )
check_function_exists ( read HAVE_READ )
check_function_exists ( sched_yield HAVE_SCHED_YIELD )
2013-06-21 01:00:40 +08:00
2012-06-04 01:27:48 +08:00
# Check for the int-type includes
check_include_files ( stdint.h HAVE_STDINT_H )
# Check our 64 bit integer sizes
check_type_size ( __int64 __INT64 )
check_type_size ( int64_t INT64_T )
check_type_size ( "long long" LONG_LONG_INT )
# Check our 32 bit integer sizes
check_type_size ( int32_t INT32_T )
check_type_size ( __int32 __INT32 )
check_type_size ( "long" LONG_INT )
check_type_size ( "int" INT )
2012-06-07 23:07:04 +08:00
if ( HAVE_INT32_T )
set ( JSON_INT32 int32_t )
elseif ( HAVE___INT32 )
2012-06-04 01:27:48 +08:00
set ( JSON_INT32 __int32 )
2018-04-28 19:54:36 +08:00
elseif ( HAVE_LONG_INT AND ( LONG_INT EQUAL 4 ) )
2012-06-04 01:27:48 +08:00
set ( JSON_INT32 long )
2018-04-28 19:54:36 +08:00
elseif ( HAVE_INT AND ( INT EQUAL 4 ) )
2012-06-04 01:27:48 +08:00
set ( JSON_INT32 int )
else ( )
2014-01-14 17:16:39 +08:00
message ( FATAL_ERROR "Could not detect a valid 32-bit integer type" )
endif ( )
check_type_size ( "unsigned long" UNSIGNED_LONG_INT )
check_type_size ( "unsigned int" UNSIGNED_INT )
2014-04-30 17:05:07 +08:00
check_type_size ( "unsigned short" UNSIGNED_SHORT )
check_type_size ( uint32_t UINT32_T )
check_type_size ( __uint32 __UINT32 )
2014-01-14 17:16:39 +08:00
if ( HAVE_UINT32_T )
set ( JSON_UINT32 uint32_t )
elseif ( HAVE___UINT32 )
set ( JSON_UINT32 __uint32 )
2018-04-28 19:54:36 +08:00
elseif ( HAVE_UNSIGNED_LONG_INT AND ( UNSIGNED_LONG_INT EQUAL 4 ) )
2014-01-14 17:16:39 +08:00
set ( JSON_UINT32 "unsigned long" )
2018-04-28 19:54:36 +08:00
elseif ( HAVE_UNSIGNED_INT AND ( UNSIGNED_INT EQUAL 4 ) )
2014-01-14 17:16:39 +08:00
set ( JSON_UINT32 "unsigned int" )
else ( )
2018-04-28 19:54:36 +08:00
message ( FATAL_ERROR "Could not detect a valid unsigned 32-bit integer type" )
2012-06-04 01:27:48 +08:00
endif ( )
2014-04-30 17:05:07 +08:00
check_type_size ( uint16_t UINT16_T )
check_type_size ( __uint16 __UINT16 )
if ( HAVE_UINT16_T )
set ( JSON_UINT16 uint16_t )
elseif ( HAVE___UINT16 )
set ( JSON_UINT16 __uint16 )
2018-04-28 19:54:36 +08:00
elseif ( HAVE_UNSIGNED_INT AND ( UNSIGNED_INT EQUAL 2 ) )
2014-04-30 17:05:07 +08:00
set ( JSON_UINT16 "unsigned int" )
2018-04-28 19:54:36 +08:00
elseif ( HAVE_UNSIGNED_SHORT AND ( UNSIGNED_SHORT EQUAL 2 ) )
2014-04-30 17:05:07 +08:00
set ( JSON_UINT16 "unsigned short" )
else ( )
2018-04-28 19:54:36 +08:00
message ( FATAL_ERROR "Could not detect a valid unsigned 16-bit integer type" )
2014-04-30 17:05:07 +08:00
endif ( )
check_type_size ( uint8_t UINT8_T )
check_type_size ( __uint8 __UINT8 )
if ( HAVE_UINT8_T )
set ( JSON_UINT8 uint8_t )
elseif ( HAVE___UINT8 )
set ( JSON_UINT8 __uint8 )
else ( )
set ( JSON_UINT8 "unsigned char" )
endif ( )
2019-09-21 01:35:56 +08:00
# Check for ssize_t and SSIZE_T existence.
2013-02-28 01:54:26 +08:00
check_type_size ( ssize_t SSIZE_T )
check_type_size ( SSIZE_T UPPERCASE_SSIZE_T )
if ( NOT HAVE_SSIZE_T )
if ( HAVE_UPPERCASE_SSIZE_T )
set ( JSON_SSIZE SSIZE_T )
else ( )
set ( JSON_SSIZE int )
endif ( )
endif ( )
set ( CMAKE_EXTRA_INCLUDE_FILES "" )
2012-06-04 01:27:48 +08:00
# Check for all the variants of strtoll
check_function_exists ( strtoll HAVE_STRTOLL )
check_function_exists ( strtoq HAVE_STRTOQ )
check_function_exists ( _strtoi64 HAVE__STRTOI64 )
# Figure out what variant we should use
if ( HAVE_STRTOLL )
set ( JSON_STRTOINT strtoll )
elseif ( HAVE_STRTOQ )
set ( JSON_STRTOINT strtoq )
elseif ( HAVE__STRTOI64 )
set ( JSON_STRTOINT _strtoi64 )
else ( )
# fallback to strtol (32 bit)
# this will set all the required variables
set ( JSON_STRTOINT strtol )
set ( JSON_INT_T long )
set ( JSON_INTEGER_FORMAT "\" ld\ "" )
endif ( )
# if we haven't defined JSON_INT_T, then we have a 64 bit conversion function.
# detect what to use for the 64 bit type.
# Note: I will prefer long long if I can get it, as that is what the automake system aimed for.
if ( NOT DEFINED JSON_INT_T )
2018-04-28 19:54:36 +08:00
if ( HAVE_LONG_LONG_INT AND ( LONG_LONG_INT EQUAL 8 ) )
2012-06-04 01:27:48 +08:00
set ( JSON_INT_T "long long" )
elseif ( HAVE_INT64_T )
set ( JSON_INT_T int64_t )
elseif ( HAVE___INT64 )
set ( JSON_INT_T __int64 )
else ( )
message ( FATAL_ERROR "Could not detect 64 bit type, although I detected the strtoll equivalent" )
endif ( )
# Apparently, Borland BCC and MSVC wants I64d,
# Borland BCC could also accept LD
# and gcc wants ldd,
# I am not sure what cygwin will want, so I will assume I64d
if ( WIN32 ) # matches both msvc and cygwin
set ( JSON_INTEGER_FORMAT "\" I64d\ "" )
else ( )
set ( JSON_INTEGER_FORMAT "\" lld\ "" )
endif ( )
endif ( )
# If locale.h and localeconv() are available, define to 1, otherwise to 0.
check_include_files ( locale.h HAVE_LOCALE_H )
check_function_exists ( localeconv HAVE_LOCALECONV )
if ( HAVE_LOCALECONV AND HAVE_LOCALE_H )
set ( JSON_HAVE_LOCALECONV 1 )
else ( )
set ( JSON_HAVE_LOCALECONV 0 )
2014-01-10 23:50:33 +08:00
endif ( )
2012-06-04 01:27:48 +08:00
# check if we have setlocale
2014-01-10 23:50:33 +08:00
check_function_exists ( setlocale HAVE_SETLOCALE )
2012-06-04 01:27:48 +08:00
# Check what the inline keyword is.
# Note that the original JSON_INLINE was always set to just 'inline', so this goes further.
check_function_keywords ( "inline" )
check_function_keywords ( "__inline" )
check_function_keywords ( "__inline__" )
if ( HAVE_INLINE )
2014-01-10 23:50:33 +08:00
set ( JSON_INLINE inline )
2012-06-04 01:27:48 +08:00
elseif ( HAVE___INLINE )
2014-01-10 23:50:33 +08:00
set ( JSON_INLINE __inline )
2012-06-04 01:27:48 +08:00
elseif ( HAVE___INLINE__ )
2014-01-10 23:50:33 +08:00
set ( JSON_INLINE __inline__ )
else ( )
2012-06-04 01:27:48 +08:00
# no inline on this platform
set ( JSON_INLINE )
2014-01-10 23:50:33 +08:00
endif ( )
2012-06-04 01:27:48 +08:00
2018-01-23 03:50:37 +08:00
check_c_source_compiles ( "int main() { unsigned long val; __sync_bool_compare_and_swap(&val, 0, 1); __sync_add_and_fetch(&val, 1); __sync_sub_and_fetch(&val, 1); return 0; } " HAVE_SYNC_BUILTINS )
check_c_source_compiles ( "int main() { char l; unsigned long v; __atomic_test_and_set(&l, __ATOMIC_RELAXED); __atomic_store_n(&v, 1, __ATOMIC_RELEASE); __atomic_load_n(&v, __ATOMIC_ACQUIRE); __atomic_add_fetch(&v, 1, __ATOMIC_ACQUIRE); __atomic_sub_fetch(&v, 1, __ATOMIC_RELEASE); return 0; }" HAVE_ATOMIC_BUILTINS )
2014-01-14 17:16:39 +08:00
2018-03-21 15:45:30 +08:00
if ( HAVE_SYNC_BUILTINS )
set ( JSON_HAVE_SYNC_BUILTINS 1 )
else ( )
set ( JSON_HAVE_SYNC_BUILTINS 0 )
endif ( )
if ( HAVE_ATOMIC_BUILTINS )
set ( JSON_HAVE_ATOMIC_BUILTINS 1 )
else ( )
set ( JSON_HAVE_ATOMIC_BUILTINS 0 )
endif ( )
2014-12-18 20:43:07 +08:00
set ( JANSSON_INITIAL_HASHTABLE_ORDER 3 CACHE STRING "Number of buckets new object hashtables contain is 2 raised to this power. The default is 3, so empty hashtables contain 2^3 = 8 buckets." )
2012-06-04 01:27:48 +08:00
# configure the public config file
2013-03-08 01:38:47 +08:00
configure_file ( ${ CMAKE_CURRENT_SOURCE_DIR } /cmake/jansson_config.h.cmake
2012-06-04 01:27:48 +08:00
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / i n c l u d e / j a n s s o n _ c o n f i g . h )
# Copy the jansson.h file to the public include folder
file ( COPY ${ CMAKE_CURRENT_SOURCE_DIR } /src/jansson.h
D E S T I N A T I O N $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / i n c l u d e / )
2014-01-14 00:13:44 +08:00
add_definitions ( -DJANSSON_USING_CMAKE )
2012-06-04 01:27:48 +08:00
# configure the private config file
2014-01-14 00:13:44 +08:00
configure_file ( ${ CMAKE_CURRENT_SOURCE_DIR } /cmake/jansson_private_config.h.cmake
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / p r i v a t e _ i n c l u d e / j a n s s o n _ p r i v a t e _ c o n f i g . h )
2012-06-04 01:27:48 +08:00
2014-01-28 16:59:43 +08:00
# and tell the source code to include it
add_definitions ( -DHAVE_CONFIG_H )
2012-06-04 01:27:48 +08:00
include_directories ( ${ CMAKE_CURRENT_BINARY_DIR } /include )
include_directories ( ${ CMAKE_CURRENT_BINARY_DIR } /private_include )
2013-02-28 01:54:26 +08:00
# Add the lib sources.
2014-01-10 23:50:33 +08:00
file ( GLOB JANSSON_SRC src/*.c )
set ( JANSSON_HDR_PRIVATE
$ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / s r c / h a s h t a b l e . h
$ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / s r c / j a n s s o n _ p r i v a t e . h
$ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / s r c / s t r b u f f e r . h
2014-01-28 16:59:43 +08:00
$ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / s r c / u t f . h
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / p r i v a t e _ i n c l u d e / j a n s s o n _ p r i v a t e _ c o n f i g . h )
2014-01-10 23:50:33 +08:00
2018-03-11 21:34:45 +08:00
set ( JANSSON_HDR_PUBLIC
2014-01-10 23:50:33 +08:00
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / i n c l u d e / j a n s s o n _ c o n f i g . h
$ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / s r c / j a n s s o n . h )
source_group ( "Library Sources" FILES ${ JANSSON_SRC } )
source_group ( "Library Private Headers" FILES ${ JANSSON_HDR_PRIVATE } )
source_group ( "Library Public Headers" FILES ${ JANSSON_HDR_PUBLIC } )
if ( JANSSON_BUILD_SHARED_LIBS )
2018-03-11 21:34:45 +08:00
add_library ( jansson SHARED
$ { J A N S S O N _ S R C }
$ { J A N S S O N _ H D R _ P R I V A T E }
$ { J A N S S O N _ H D R _ P U B L I C }
2014-01-10 23:50:33 +08:00
s r c / j a n s s o n . d e f )
build: Add a symbol version to all exported symbols for glibc
The --default-symver linker option attaches a default version definition
(the SONAME) to every exported symbol. It is supported since at least
GNU binutils 2.22 in 2011 (older versions not tested).
With this version definition, newly-linked binaries that depend on the
jansson shared library will refer to its symbols in a versioned form,
preventing their references from being resolved to a symbol of the same
name exported by json-c or json-glib if those libraries appear in
dependency search order before jansson, which will usually result in
a crash. This is necessary because ELF symbol resolution normally uses
a single flat namespace, not a tree like Windows symbol resolution.
At least one symbol (json_object_iter_next()) is exported by all three
JSON libraries.
Linking with -Bsymbolic is not enough to have this effect in all cases,
because -Bsymbolic only affects symbol lookup within a shared object,
for example when parse_json() calls json_decref(). It does not affect
calls from external code into jansson, unless jansson was statically
linked into the external caller.
This change will also not prevent code that depends on json-c or
json-glib from finding jansson's symbols and crashing; to prevent
that, a corresponding change in json-c or json-glib would be needed.
Adding a symbol-version is a backwards-compatible change, but once
added, removing or changing the symbol-version would be an incompatible
change that requires a SONAME bump.
Resolves: https://github.com/akheron/jansson/issues/523
(when combined with an equivalent change to json-c).
Signed-off-by: Simon McVittie <smcv@collabora.com>
2020-06-30 01:28:38 +08:00
if ( LIBC_IS_GLIBC )
set ( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--default-symver" )
endif ( )
2014-01-10 23:50:33 +08:00
set_target_properties ( jansson PROPERTIES
2013-02-28 01:54:26 +08:00
V E R S I O N $ { J A N S S O N _ V E R S I O N }
S O V E R S I O N $ { J A N S S O N _ S O V E R S I O N } )
2014-01-10 23:50:33 +08:00
else ( )
2018-04-28 19:54:36 +08:00
add_library ( jansson STATIC
2014-01-10 23:50:33 +08:00
$ { J A N S S O N _ S R C }
2018-03-11 21:34:45 +08:00
$ { J A N S S O N _ H D R _ P R I V A T E }
2014-01-10 23:50:33 +08:00
$ { J A N S S O N _ H D R _ P U B L I C } )
2018-04-28 19:54:36 +08:00
set_target_properties ( jansson PROPERTIES
P O S I T I O N _ I N D E P E N D E N T _ C O D E t r u e )
2014-01-10 23:50:33 +08:00
endif ( )
2013-02-28 01:54:26 +08:00
2015-01-13 23:17:48 +08:00
if ( JANSSON_EXAMPLES )
2018-03-11 22:11:09 +08:00
add_executable ( simple_parse "${CMAKE_CURRENT_SOURCE_DIR}/examples/simple_parse.c" )
2015-01-13 23:17:48 +08:00
target_link_libraries ( simple_parse jansson )
endif ( )
2013-05-06 20:34:52 +08:00
2012-06-04 01:27:48 +08:00
# For building Documentation (uses Sphinx)
2014-01-10 23:50:33 +08:00
option ( JANSSON_BUILD_DOCS "Build documentation (uses python-sphinx)." ON )
if ( JANSSON_BUILD_DOCS )
2013-04-24 22:14:00 +08:00
find_package ( Sphinx )
2012-06-04 01:27:48 +08:00
2013-04-24 22:14:00 +08:00
if ( NOT SPHINX_FOUND )
2018-03-11 21:34:45 +08:00
message ( WARNING " Sphinx not found. Cannot generate documentation!
2014-01-14 00:13:44 +08:00
S e t - D J A N S S O N _ B U I L D _ D O C S = O F F t o g e t r i d o f t h i s m e s s a g e . " )
2013-04-24 22:14:00 +08:00
else ( )
if ( Sphinx_VERSION_STRING VERSION_LESS 1.0 )
2018-03-11 21:34:45 +08:00
message ( WARNING " Your Sphinx version is too old!
T h i s p r o j e c t r e q u i r e s S p h i n x v 1 . 0 o r a b o v e t o p r o d u c e
2013-04-24 22:14:00 +08:00
p r o p e r documentation ( you have v ${ Sphinx_VERSION_STRING } ) .
Y o u w i l l g e t o u t p u t b u t i t w i l l h a v e e r r o r s . " )
endif ( )
# configured documentation tools and intermediate build results
set ( BINARY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/_build" )
# Sphinx cache with pickled ReST documents
set ( SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees" )
# CMake could be used to build the conf.py file too,
# eg it could automatically write the version of the program or change the theme.
# if(NOT DEFINED SPHINX_THEME)
# set(SPHINX_THEME default)
# endif()
#
# if(NOT DEFINED SPHINX_THEME_DIR)
# set(SPHINX_THEME_DIR)
# endif()
#
# configure_file(
# "${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in"
# "${BINARY_BUILD_DIR}/conf.py"
# @ONLY)
# TODO: Add support for all sphinx builders: http://sphinx-doc.org/builders.html
# Add documentation targets.
set ( DOC_TARGETS html )
2014-01-10 23:50:33 +08:00
option ( JANSSON_BUILD_MAN "Create a target for building man pages." ON )
2013-04-24 22:14:00 +08:00
2014-01-10 23:50:33 +08:00
if ( JANSSON_BUILD_MAN )
2013-04-24 22:14:00 +08:00
if ( Sphinx_VERSION_STRING VERSION_LESS 1.0 )
message ( WARNING "Sphinx version 1.0 > is required to build man pages. You have v${Sphinx_VERSION_STRING}." )
else ( )
list ( APPEND DOC_TARGETS man )
endif ( )
endif ( )
2014-01-10 23:50:33 +08:00
option ( JANSSON_BUILD_LATEX "Create a target for building latex docs (to create PDF)." OFF )
2013-04-24 22:14:00 +08:00
2014-01-10 23:50:33 +08:00
if ( JANSSON_BUILD_LATEX )
2013-04-24 22:14:00 +08:00
find_package ( LATEX )
if ( NOT LATEX_COMPILER )
message ( "Couldn't find Latex, can't build latex docs using Sphinx" )
else ( )
message ( "Latex found! If you have problems building, see Sphinx documentation for required Latex packages." )
list ( APPEND DOC_TARGETS latex )
endif ( )
endif ( )
2018-03-11 21:34:45 +08:00
2013-04-24 22:14:00 +08:00
# The doc target will build all documentation targets.
add_custom_target ( doc )
foreach ( DOC_TARGET ${ DOC_TARGETS } )
add_custom_target ( ${ DOC_TARGET }
$ { S P H I N X _ E X E C U T A B L E }
# -q # Enable for quiet mode
- b $ { D O C _ T A R G E T }
- d " $ { S P H I N X _ C A C H E _ D I R } "
# -c "${BINARY_BUILD_DIR}" # enable if using cmake-generated conf.py
" $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / d o c "
" $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / d o c / $ { D O C _ T A R G E T } "
C O M M E N T " B u i l d i n g $ { D O C _ T A R G E T } d o c u m e n t a t i o n w i t h S p h i n x " )
add_dependencies ( doc ${ DOC_TARGET } )
endforeach ( )
message ( "Building documentation enabled for: ${DOC_TARGETS}" )
endif ( )
2012-06-04 01:27:48 +08:00
endif ( )
2014-01-10 23:50:33 +08:00
option ( JANSSON_WITHOUT_TESTS "Don't build tests ('make test' to execute tests)" OFF )
2012-06-04 01:27:48 +08:00
2014-01-10 23:50:33 +08:00
if ( NOT JANSSON_WITHOUT_TESTS )
option ( JANSSON_TEST_WITH_VALGRIND "Enable valgrind tests." OFF )
2012-06-04 01:27:48 +08:00
ENABLE_TESTING ( )
2014-01-10 23:50:33 +08:00
if ( JANSSON_TEST_WITH_VALGRIND )
2013-02-28 01:54:26 +08:00
# TODO: Add FindValgrind.cmake instead of having a hardcoded path.
2013-03-15 04:18:21 +08:00
2014-02-12 14:54:06 +08:00
add_definitions ( -DVALGRIND )
2012-06-04 01:27:48 +08:00
# enable valgrind
2013-02-28 07:16:32 +08:00
set ( CMAKE_MEMORYCHECK_COMMAND valgrind )
2013-03-15 04:18:21 +08:00
set ( CMAKE_MEMORYCHECK_COMMAND_OPTIONS
2014-01-28 21:07:59 +08:00
" - - e r r o r - e x i t c o d e = 1 - - l e a k - c h e c k = f u l l - - s h o w - r e a c h a b l e = y e s - - t r a c k - o r i g i n s = y e s - q " )
2012-06-04 01:27:48 +08:00
2013-03-15 04:18:21 +08:00
set ( MEMCHECK_COMMAND
2013-02-28 07:16:32 +08:00
" $ { C M A K E _ M E M O R Y C H E C K _ C O M M A N D } $ { C M A K E _ M E M O R Y C H E C K _ C O M M A N D _ O P T I O N S } " )
2012-06-04 01:27:48 +08:00
separate_arguments ( MEMCHECK_COMMAND )
endif ( )
2013-02-28 01:54:26 +08:00
#
# Test suites.
#
if ( CMAKE_COMPILER_IS_GNUCC )
2014-01-16 14:01:35 +08:00
add_definitions ( -Wall -Wextra -Wdeclaration-after-statement )
2013-02-28 07:16:32 +08:00
endif ( )
2013-02-28 01:54:26 +08:00
2013-03-15 04:18:21 +08:00
set ( api_tests
2013-02-28 01:54:26 +08:00
t e s t _ a r r a y
t e s t _ c o p y
2018-02-13 17:35:37 +08:00
t e s t _ c h a o s
2013-02-28 01:54:26 +08:00
t e s t _ d u m p
t e s t _ d u m p _ c a l l b a c k
t e s t _ e q u a l
t e s t _ l o a d
t e s t _ l o a d b
2018-03-07 12:28:14 +08:00
t e s t _ l o a d _ c a l l b a c k
2013-02-28 01:54:26 +08:00
t e s t _ n u m b e r
t e s t _ o b j e c t
t e s t _ p a c k
t e s t _ s i m p l e
2018-02-09 02:52:10 +08:00
t e s t _ s p r i n t f
2013-02-28 01:54:26 +08:00
t e s t _ u n p a c k )
# Doing arithmetic on void pointers is not allowed by Microsofts compiler
# such as secure_malloc and secure_free is doing, so exclude it for now.
if ( NOT MSVC )
list ( APPEND api_tests test_memory_funcs )
endif ( )
# Helper macro for building and linking a test program.
macro ( build_testprog name dir )
2013-02-28 07:16:32 +08:00
add_executable ( ${ name } ${ dir } / ${ name } .c )
2013-02-28 01:54:26 +08:00
add_dependencies ( ${ name } jansson )
target_link_libraries ( ${ name } jansson )
endmacro ( build_testprog )
# Create executables and tests/valgrind tests for API tests.
foreach ( test ${ api_tests } )
2018-03-11 22:11:09 +08:00
build_testprog ( ${ test } ${ CMAKE_CURRENT_SOURCE_DIR } /test/suites/api )
2013-02-28 01:54:26 +08:00
2014-01-28 21:07:59 +08:00
if ( JANSSON_TEST_WITH_VALGRIND )
add_test ( memcheck__ ${ test }
2014-12-19 14:35:31 +08:00
$ { M E M C H E C K _ C O M M A N D } $ { C M A K E _ R U N T I M E _ O U T P U T _ D I R E C T O R Y } / $ { t e s t }
W O R K I N G _ D I R E C T O R Y $ { J A N S S O N _ T E M P _ D I R } )
2014-01-28 21:07:59 +08:00
else ( )
2014-12-19 14:35:31 +08:00
add_test ( ${ test }
$ { C M A K E _ R U N T I M E _ O U T P U T _ D I R E C T O R Y } / $ { t e s t }
W O R K I N G _ D I R E C T O R Y $ { J A N S S O N _ T E M P _ D I R } )
2013-02-28 07:16:32 +08:00
endif ( )
endforeach ( )
2013-02-28 01:54:26 +08:00
# Test harness for the suites tests.
2018-03-11 22:11:09 +08:00
build_testprog ( json_process ${ CMAKE_CURRENT_SOURCE_DIR } /test/bin )
2013-02-28 01:54:26 +08:00
2014-12-11 05:30:33 +08:00
set ( SUITE_TEST_CMD ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /json_process )
2013-02-28 01:54:26 +08:00
set ( SUITES encoding-flags valid invalid invalid-unicode )
foreach ( SUITE ${ SUITES } )
2018-03-11 22:11:09 +08:00
file ( GLOB TESTDIRS test/suites/ ${ SUITE } /* )
2014-01-28 21:07:59 +08:00
2013-02-28 01:54:26 +08:00
foreach ( TESTDIR ${ TESTDIRS } )
if ( IS_DIRECTORY ${ TESTDIR } )
get_filename_component ( TNAME ${ TESTDIR } NAME )
2014-01-28 21:07:59 +08:00
if ( JANSSON_TEST_WITH_VALGRIND )
add_test ( memcheck__ ${ SUITE } __ ${ TNAME }
$ { M E M C H E C K _ C O M M A N D } $ { S U I T E _ T E S T _ C M D } $ { T E S T D I R } )
else ( )
add_test ( ${ SUITE } __ ${ TNAME }
$ { S U I T E _ T E S T _ C M D } $ { T E S T D I R } )
endif ( )
2013-03-15 04:15:42 +08:00
if ( ( ${ SUITE } STREQUAL "valid" OR ${ SUITE } STREQUAL "invalid" ) AND NOT EXISTS ${ TESTDIR } /nostrip )
2014-01-28 21:07:59 +08:00
if ( JANSSON_TEST_WITH_VALGRIND )
add_test ( memcheck__ ${ SUITE } __ ${ TNAME } __strip
$ { M E M C H E C K _ C O M M A N D } $ { S U I T E _ T E S T _ C M D } - - s t r i p $ { T E S T D I R } )
else ( )
add_test ( ${ SUITE } __ ${ TNAME } __strip
$ { S U I T E _ T E S T _ C M D } - - s t r i p $ { T E S T D I R } )
endif ( )
2013-03-15 04:15:42 +08:00
endif ( )
2013-02-28 07:16:32 +08:00
endif ( )
endforeach ( )
2013-02-28 01:54:26 +08:00
endforeach ( )
2013-04-24 22:14:00 +08:00
2014-12-11 05:30:33 +08:00
if ( JANSSON_COVERAGE )
setup_target_for_coverage (
c o v e r a g e # Coverage make target "make coverage".
c o v e r a g e # Name of output directory.
m a k e # Name of test runner executable.
t e s t ) # Arguments to the test runner above (make test).
if ( JANSSON_COVERALLS )
set ( COVERAGE_SRCS ${ JANSSON_SRC } )
coveralls_setup ( "${COVERAGE_SRCS}" ${ JANSSON_COVERALLS_UPLOAD } )
endif ( )
endif ( )
# Enable using "make check" just like the autotools project.
# By default cmake creates a target "make test"
2018-03-11 21:34:45 +08:00
add_custom_target ( check COMMAND ${ CMAKE_CTEST_COMMAND }
2013-04-24 22:14:00 +08:00
D E P E N D S j s o n _ p r o c e s s $ { a p i _ t e s t s } )
2012-06-04 01:27:48 +08:00
endif ( )
2014-01-10 23:50:33 +08:00
#
# Installation preparation.
#
# Allow the user to override installation directories.
set ( JANSSON_INSTALL_LIB_DIR lib CACHE PATH "Installation directory for libraries" )
set ( JANSSON_INSTALL_BIN_DIR bin CACHE PATH "Installation directory for executables" )
set ( JANSSON_INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files" )
if ( WIN32 AND NOT CYGWIN )
set ( DEF_INSTALL_CMAKE_DIR cmake )
else ( )
set ( DEF_INSTALL_CMAKE_DIR lib/cmake/jansson )
endif ( )
set ( JANSSON_INSTALL_CMAKE_DIR ${ DEF_INSTALL_CMAKE_DIR } CACHE PATH "Installation directory for CMake files" )
2016-02-10 19:33:48 +08:00
# Create pkg-conf file.
# (We use the same files as ./configure does, so we
# have to defined the same variables used there).
set ( prefix ${ CMAKE_INSTALL_PREFIX } )
2017-10-30 02:27:25 +08:00
set ( exec_prefix "\${prefix}" )
set ( libdir "\${exec_prefix}/${JANSSON_INSTALL_LIB_DIR}" )
set ( includedir "\${prefix}/${JANSSON_INSTALL_INCLUDE_DIR}" )
2016-02-10 19:33:48 +08:00
set ( VERSION ${ JANSSON_DISPLAY_VERSION } )
configure_file ( ${ CMAKE_CURRENT_SOURCE_DIR } /jansson.pc.in
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / j a n s s o n . p c @ O N L Y )
2018-03-11 22:51:43 +08:00
# Make sure the paths are relative.
2014-01-10 23:50:33 +08:00
foreach ( p LIB BIN INCLUDE CMAKE )
set ( var JANSSON_INSTALL_ ${ p } _DIR )
endforeach ( )
# Generate the config file for the build-tree.
2018-03-11 21:34:45 +08:00
set ( JANSSON__INCLUDE_DIRS
2018-03-11 22:11:09 +08:00
" $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / i n c l u d e "
" $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / i n c l u d e " )
2014-01-14 00:13:44 +08:00
set ( JANSSON_INCLUDE_DIRS ${ JANSSON__INCLUDE_DIRS } CACHE PATH "Jansson include directories" )
2018-03-11 22:11:09 +08:00
configure_file ( ${ CMAKE_CURRENT_SOURCE_DIR } /cmake/janssonConfig.cmake.in
2018-03-11 22:51:43 +08:00
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / j a n s s o n C o n f i g . c m a k e
@ O N L Y )
2014-01-10 23:50:33 +08:00
# Generate the config file for the installation tree.
2018-03-11 22:37:15 +08:00
include ( CMakePackageConfigHelpers )
2018-03-11 22:27:48 +08:00
2018-03-11 22:24:27 +08:00
write_basic_package_version_file (
2018-03-11 22:43:38 +08:00
" $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / c m a k e / j a n s s o n C o n f i g V e r s i o n . c m a k e "
2018-03-11 22:37:15 +08:00
V E R S I O N $ { J A N S S O N _ V E R S I O N }
C O M P A T I B I L I T Y E x a c t V e r s i o n
2018-03-11 22:24:27 +08:00
)
configure_package_config_file (
" c m a k e / j a n s s o n C o n f i g . c m a k e . i n "
" $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / c m a k e / j a n s s o n C o n f i g . c m a k e "
I N S T A L L _ D E S T I N A T I O N " $ { J A N S S O N _ I N S T A L L _ C M A K E _ D I R } "
)
2014-01-10 23:50:33 +08:00
#
# Install targets.
#
2016-09-11 13:04:49 +08:00
option ( JANSSON_INSTALL "Generate installation target" ON )
if ( JANSSON_INSTALL )
2018-03-11 22:24:27 +08:00
install ( TARGETS jansson
E X P O R T j a n s s o n T a r g e t s
L I B R A R Y D E S T I N A T I O N " l i b "
A R C H I V E D E S T I N A T I O N " l i b "
R U N T I M E D E S T I N A T I O N " b i n "
I N C L U D E S D E S T I N A T I O N " i n c l u d e " )
install ( FILES ${ JANSSON_HDR_PUBLIC }
D E S T I N A T I O N " i n c l u d e " )
# Install the pkg-config.
install ( FILES
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / j a n s s o n . p c
D E S T I N A T I O N l i b / p k g c o n f i g )
# Install the configs.
install ( FILES
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / c m a k e / j a n s s o n C o n f i g . c m a k e
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / c m a k e / j a n s s o n C o n f i g V e r s i o n . c m a k e
D E S T I N A T I O N " $ { J A N S S O N _ I N S T A L L _ C M A K E _ D I R } " )
# Install exports for the install-tree.
install ( EXPORT janssonTargets
2018-03-11 22:51:43 +08:00
N A M E S P A C E j a n s s o n : :
2018-03-11 22:24:27 +08:00
D E S T I N A T I O N " $ { J A N S S O N _ I N S T A L L _ C M A K E _ D I R } " )
2016-09-11 13:04:49 +08:00
endif ( )
2014-01-10 23:50:33 +08:00
2014-01-14 00:13:44 +08:00
# For use when simply using add_library from a parent project to build jansson.
2018-03-11 21:52:48 +08:00
set ( JANSSON_LIBRARIES jansson CACHE STRING "jansson libraries" )