xref: /NextBSD/contrib/jansson/CMakeLists.txt (revision 33da5adc555b3bc29986eeadca03829e4ad06b1e)
1# Notes:
2#
3# Author: Paul Harris, June 2012
4# Additions: Joakim Soderberg, Febuary 2013
5#
6# Supports: building static/shared, release/debug/etc, can also build html docs
7# and some of the tests.
8# Note that its designed for out-of-tree builds, so it will not pollute your
9# source tree.
10#
11# TODO 1: Finish implementing tests. api tests are working, but the valgrind
12# variants are not flagging problems.
13#
14# TODO 2: There is a check_exports script that would try and incorporate.
15#
16# TODO 3: Consolidate version numbers, currently the version number is written
17# into: * cmake (here) * autotools (the configure) * source code header files.
18# Should not be written directly into header files, autotools/cmake can do
19# that job.
20#
21# Brief intro on how to use cmake:
22# > mkdir build (somewhere - we do out-of-tree builds)
23# > use cmake, ccmake, or cmake-gui to configure the project. for linux, you
24# can only choose one variant: release,debug,etc... and static or shared.
25# >> example:
26# >> cd build
27# >> ccmake -i ../path_to_jansson_dir
28# >>  inside, configure your options. press C until there are no lines
29#     with * next to them.
30# >>  note, I like to configure the 'install' path to ../install, so I get
31#     self-contained clean installs I can point other projects to.
32# >>  press G to 'generate' the project files.
33# >> make (to build the project)
34# >> make install
35# >> make test (to run the tests, if you enabled them)
36#
37# Brief description on how it works:
38# There is a small heirachy of CMakeLists.txt files which define how the
39# project is built.
40# Header file detection etc is done, and the results are written into config.h
41# and jansson_config.h, which are generated from the corresponding
42# config.h.cmake and jansson_config.h.cmake template files.
43# The generated header files end up in the build directory - not in
44# the source directory.
45# The rest is down to the usual make process.
46
47
48
49cmake_minimum_required (VERSION 2.8)
50# required for exports? cmake_minimum_required (VERSION 2.8.6)
51project (jansson C)
52
53# Options
54option(JANSSON_BUILD_SHARED_LIBS "Build shared libraries." OFF)
55option(USE_URANDOM "Use /dev/urandom to seed the hash function." ON)
56option(USE_WINDOWS_CRYPTOAPI "Use CryptGenRandom to seed the hash function." ON)
57
58if (MSVC)
59   # This option must match the settings used in your program, in particular if you
60	# are linking statically
61	option(JANSSON_STATIC_CRT "Link the static CRT libraries" OFF )
62endif ()
63
64# Set some nicer output dirs.
65set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
66set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
67set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
68
69# Give the debug version a different postfix for windows,
70# so both the debug and release version can be built in the
71# same build-tree on Windows (MSVC).
72if (WIN32)
73   set(CMAKE_DEBUG_POSTFIX "_d")
74else (WIN32)
75endif (WIN32)
76
77# This is how I thought it should go
78# set (JANSSON_VERSION "2.3.1")
79# set (JANSSON_SOVERSION 2)
80
81set(JANSSON_DISPLAY_VERSION "2.7")
82
83# This is what is required to match the same numbers as automake's
84set(JANSSON_VERSION "4.7.0")
85set(JANSSON_SOVERSION 4)
86
87# for CheckFunctionKeywords
88set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
89
90include (CheckCSourceCompiles)
91include (CheckFunctionExists)
92include (CheckFunctionKeywords)
93include (CheckIncludeFiles)
94include (CheckTypeSize)
95
96if (MSVC)
97   # Turn off Microsofts "security" warnings.
98   add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo" )
99
100   if (STATIC_CRT)
101      set(CMAKE_C_FLAGS_RELEASE "/MT")
102      set(CMAKE_C_FLAGS_DEBUG "/MTd")
103   endif()
104
105endif()
106
107if (NOT WIN32 AND (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX))
108   add_definitions("-fPIC")
109endif()
110
111check_include_files (endian.h HAVE_ENDIAN_H)
112check_include_files (fcntl.h HAVE_FCNTL_H)
113check_include_files (sched.h HAVE_SCHED_H)
114check_include_files (unistd.h HAVE_UNISTD_H)
115check_include_files (sys/param.h HAVE_SYS_PARAM_H)
116check_include_files (sys/stat.h HAVE_SYS_STAT_H)
117check_include_files (sys/time.h HAVE_SYS_TIME_H)
118check_include_files (sys/time.h HAVE_SYS_TYPES_H)
119
120check_function_exists (close HAVE_CLOSE)
121check_function_exists (getpid HAVE_GETPID)
122check_function_exists (gettimeofday HAVE_GETTIMEOFDAY)
123check_function_exists (open HAVE_OPEN)
124check_function_exists (read HAVE_READ)
125check_function_exists (sched_yield HAVE_SCHED_YIELD)
126
127# Check for the int-type includes
128check_include_files (stdint.h HAVE_STDINT_H)
129
130# Check our 64 bit integer sizes
131check_type_size (__int64 __INT64)
132check_type_size (int64_t INT64_T)
133check_type_size ("long long" LONG_LONG_INT)
134
135# Check our 32 bit integer sizes
136check_type_size (int32_t INT32_T)
137check_type_size (__int32 __INT32)
138check_type_size ("long" LONG_INT)
139check_type_size ("int" INT)
140if (HAVE_INT32_T)
141   set (JSON_INT32 int32_t)
142elseif (HAVE___INT32)
143   set (JSON_INT32 __int32)
144elseif (HAVE_LONG_INT AND (${LONG_INT} EQUAL 4))
145   set (JSON_INT32 long)
146elseif (HAVE_INT AND (${INT} EQUAL 4))
147   set (JSON_INT32 int)
148else ()
149   message (FATAL_ERROR "Could not detect a valid 32-bit integer type")
150endif ()
151
152check_type_size ("unsigned long" UNSIGNED_LONG_INT)
153check_type_size ("unsigned int" UNSIGNED_INT)
154check_type_size ("unsigned short" UNSIGNED_SHORT)
155
156check_type_size (uint32_t UINT32_T)
157check_type_size (__uint32 __UINT32)
158if (HAVE_UINT32_T)
159   set (JSON_UINT32 uint32_t)
160elseif (HAVE___UINT32)
161   set (JSON_UINT32 __uint32)
162elseif (HAVE_UNSIGNED_LONG_INT AND (${UNSIGNED_LONG_INT} EQUAL 4))
163   set (JSON_UINT32 "unsigned long")
164elseif (HAVE_UNSIGNED_INT AND (${UNSIGNED_INT} EQUAL 4))
165   set (JSON_UINT32 "unsigned int")
166else ()
167   message (FATAL_ERROR "Could not detect a valid unsigned 32-bit integer type")
168endif ()
169
170check_type_size (uint16_t UINT16_T)
171check_type_size (__uint16 __UINT16)
172if (HAVE_UINT16_T)
173   set (JSON_UINT16 uint16_t)
174elseif (HAVE___UINT16)
175   set (JSON_UINT16 __uint16)
176elseif (HAVE_UNSIGNED_INT AND (${UNSIGNED_INT} EQUAL 2))
177   set (JSON_UINT16 "unsigned int")
178elseif (HAVE_UNSIGNED_SHORT AND (${UNSIGNED_SHORT} EQUAL 2))
179   set (JSON_UINT16 "unsigned short")
180else ()
181   message (FATAL_ERROR "Could not detect a valid unsigned 16-bit integer type")
182endif ()
183
184check_type_size (uint8_t UINT8_T)
185check_type_size (__uint8 __UINT8)
186if (HAVE_UINT8_T)
187   set (JSON_UINT8 uint8_t)
188elseif (HAVE___UINT8)
189   set (JSON_UINT8 __uint8)
190else ()
191   set (JSON_UINT8 "unsigned char")
192endif ()
193
194# Check for ssize_t and SSIZE_T existance.
195check_type_size(ssize_t SSIZE_T)
196check_type_size(SSIZE_T UPPERCASE_SSIZE_T)
197if(NOT HAVE_SSIZE_T)
198   if(HAVE_UPPERCASE_SSIZE_T)
199      set(JSON_SSIZE SSIZE_T)
200   else()
201      set(JSON_SSIZE int)
202   endif()
203endif()
204set(CMAKE_EXTRA_INCLUDE_FILES "")
205
206# Check for all the variants of strtoll
207check_function_exists (strtoll HAVE_STRTOLL)
208check_function_exists (strtoq HAVE_STRTOQ)
209check_function_exists (_strtoi64 HAVE__STRTOI64)
210
211# Figure out what variant we should use
212if (HAVE_STRTOLL)
213   set (JSON_STRTOINT strtoll)
214elseif (HAVE_STRTOQ)
215   set (JSON_STRTOINT strtoq)
216elseif (HAVE__STRTOI64)
217   set (JSON_STRTOINT _strtoi64)
218else ()
219   # fallback to strtol (32 bit)
220   # this will set all the required variables
221   set (JSON_STRTOINT strtol)
222   set (JSON_INT_T long)
223   set (JSON_INTEGER_FORMAT "\"ld\"")
224endif ()
225
226# if we haven't defined JSON_INT_T, then we have a 64 bit conversion function.
227# detect what to use for the 64 bit type.
228# Note: I will prefer long long if I can get it, as that is what the automake system aimed for.
229if (NOT DEFINED JSON_INT_T)
230   if (HAVE_LONG_LONG_INT AND (${LONG_LONG_INT} EQUAL 8))
231      set (JSON_INT_T "long long")
232   elseif (HAVE_INT64_T)
233      set (JSON_INT_T int64_t)
234   elseif (HAVE___INT64)
235      set (JSON_INT_T __int64)
236   else ()
237      message (FATAL_ERROR "Could not detect 64 bit type, although I detected the strtoll equivalent")
238   endif ()
239
240   # Apparently, Borland BCC and MSVC wants I64d,
241   # Borland BCC could also accept LD
242   # and gcc wants ldd,
243   # I am not sure what cygwin will want, so I will assume I64d
244
245   if (WIN32) # matches both msvc and cygwin
246      set (JSON_INTEGER_FORMAT "\"I64d\"")
247   else ()
248      set (JSON_INTEGER_FORMAT "\"lld\"")
249   endif ()
250endif ()
251
252
253# If locale.h and localeconv() are available, define to 1, otherwise to 0.
254check_include_files (locale.h HAVE_LOCALE_H)
255check_function_exists (localeconv HAVE_LOCALECONV)
256
257if (HAVE_LOCALECONV AND HAVE_LOCALE_H)
258   set (JSON_HAVE_LOCALECONV 1)
259else ()
260   set (JSON_HAVE_LOCALECONV 0)
261endif()
262
263# check if we have setlocale
264check_function_exists(setlocale HAVE_SETLOCALE)
265
266# Check what the inline keyword is.
267# Note that the original JSON_INLINE was always set to just 'inline', so this goes further.
268check_function_keywords("inline")
269check_function_keywords("__inline")
270check_function_keywords("__inline__")
271
272if (HAVE_INLINE)
273   set(JSON_INLINE inline)
274elseif (HAVE___INLINE)
275   set(JSON_INLINE __inline)
276elseif (HAVE___INLINE__)
277   set(JSON_INLINE __inline__)
278else()
279   # no inline on this platform
280   set (JSON_INLINE)
281endif()
282
283# Find our snprintf
284check_function_exists (snprintf HAVE_SNPRINTF)
285check_function_exists (_snprintf HAVE__SNPRINTF)
286
287if (HAVE_SNPRINTF)
288   set(JSON_SNPRINTF snprintf)
289elseif (HAVE__SNPRINTF)
290   set(JSON_SNPRINTF _snprintf)
291endif ()
292
293check_c_source_compiles ("int main() { unsigned long val; __sync_bool_compare_and_swap(&val, 0, 1); return 0; } " HAVE_SYNC_BUILTINS)
294check_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); return 0; }" HAVE_ATOMIC_BUILTINS)
295
296# Create pkg-conf file.
297# (We use the same files as ./configure does, so we
298#  have to defined the same variables used there).
299if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
300  set(CMAKE_INSTALL_LIBDIR lib)
301endif(NOT DEFINED CMAKE_INSTALL_LIBDIR)
302set(prefix      ${CMAKE_INSTALL_PREFIX})
303set(exec_prefix ${CMAKE_INSTALL_PREFIX})
304set(libdir      ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
305set(VERSION     ${JANSSON_DISPLAY_VERSION})
306configure_file(${CMAKE_CURRENT_SOURCE_DIR}/jansson.pc.in
307               ${CMAKE_CURRENT_BINARY_DIR}/jansson.pc @ONLY)
308
309# configure the public config file
310configure_file (${CMAKE_CURRENT_SOURCE_DIR}/cmake/jansson_config.h.cmake
311                ${CMAKE_CURRENT_BINARY_DIR}/include/jansson_config.h)
312
313# Copy the jansson.h file to the public include folder
314file (COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/jansson.h
315           DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/)
316
317add_definitions(-DJANSSON_USING_CMAKE)
318
319# configure the private config file
320configure_file (${CMAKE_CURRENT_SOURCE_DIR}/cmake/jansson_private_config.h.cmake
321                ${CMAKE_CURRENT_BINARY_DIR}/private_include/jansson_private_config.h)
322
323# and tell the source code to include it
324add_definitions(-DHAVE_CONFIG_H)
325
326include_directories (${CMAKE_CURRENT_BINARY_DIR}/include)
327include_directories (${CMAKE_CURRENT_BINARY_DIR}/private_include)
328
329# Add the lib sources.
330file(GLOB JANSSON_SRC src/*.c)
331
332set(JANSSON_HDR_PRIVATE
333   ${CMAKE_CURRENT_SOURCE_DIR}/src/hashtable.h
334   ${CMAKE_CURRENT_SOURCE_DIR}/src/jansson_private.h
335   ${CMAKE_CURRENT_SOURCE_DIR}/src/strbuffer.h
336   ${CMAKE_CURRENT_SOURCE_DIR}/src/utf.h
337   ${CMAKE_CURRENT_BINARY_DIR}/private_include/jansson_private_config.h)
338
339set(JANSSON_HDR_PUBLIC
340   ${CMAKE_CURRENT_BINARY_DIR}/include/jansson_config.h
341   ${CMAKE_CURRENT_SOURCE_DIR}/src/jansson.h)
342
343source_group("Library Sources" FILES ${JANSSON_SRC})
344source_group("Library Private Headers" FILES ${JANSSON_HDR_PRIVATE})
345source_group("Library Public Headers" FILES ${JANSSON_HDR_PUBLIC})
346
347if(JANSSON_BUILD_SHARED_LIBS)
348   add_library(jansson SHARED
349      ${JANSSON_SRC}
350      ${JANSSON_HDR_PRIVATE}
351      ${JANSSON_HDR_PUBLIC}
352      src/jansson.def)
353
354   set_target_properties(jansson PROPERTIES
355      VERSION ${JANSSON_VERSION}
356      SOVERSION ${JANSSON_SOVERSION})
357else()
358   add_library(jansson
359      ${JANSSON_SRC}
360      ${JANSSON_HDR_PRIVATE}
361      ${JANSSON_HDR_PUBLIC})
362endif()
363
364
365# For building Documentation (uses Sphinx)
366option(JANSSON_BUILD_DOCS "Build documentation (uses python-sphinx)." ON)
367if (JANSSON_BUILD_DOCS)
368   find_package(Sphinx)
369
370   if (NOT SPHINX_FOUND)
371      message(WARNING "Sphinx not found. Cannot generate documentation!
372      Set -DJANSSON_BUILD_DOCS=OFF to get rid of this message.")
373   else()
374      if (Sphinx_VERSION_STRING VERSION_LESS 1.0)
375         message(WARNING "Your Sphinx version is too old!
376               This project requires Sphinx v1.0 or above to produce
377               proper documentation (you have v${Sphinx_VERSION_STRING}).
378               You will get output but it will have errors.")
379      endif()
380
381      # configured documentation tools and intermediate build results
382      set(BINARY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/_build")
383
384      # Sphinx cache with pickled ReST documents
385      set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees")
386
387      # CMake could be used to build the conf.py file too,
388      # eg it could automatically write the version of the program or change the theme.
389      # if(NOT DEFINED SPHINX_THEME)
390      #    set(SPHINX_THEME default)
391      # endif()
392      #
393      # if(NOT DEFINED SPHINX_THEME_DIR)
394      #    set(SPHINX_THEME_DIR)
395      # endif()
396      #
397      # configure_file(
398      #    "${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in"
399      #    "${BINARY_BUILD_DIR}/conf.py"
400      #    @ONLY)
401
402      # TODO: Add support for all sphinx builders: http://sphinx-doc.org/builders.html
403
404      # Add documentation targets.
405      set(DOC_TARGETS html)
406
407      option(JANSSON_BUILD_MAN "Create a target for building man pages." ON)
408
409      if (JANSSON_BUILD_MAN)
410         if (Sphinx_VERSION_STRING VERSION_LESS 1.0)
411            message(WARNING "Sphinx version 1.0 > is required to build man pages. You have v${Sphinx_VERSION_STRING}.")
412         else()
413            list(APPEND DOC_TARGETS man)
414         endif()
415      endif()
416
417      option(JANSSON_BUILD_LATEX "Create a target for building latex docs (to create PDF)." OFF)
418
419      if (JANSSON_BUILD_LATEX)
420         find_package(LATEX)
421
422         if (NOT LATEX_COMPILER)
423            message("Couldn't find Latex, can't build latex docs using Sphinx")
424         else()
425            message("Latex found! If you have problems building, see Sphinx documentation for required Latex packages.")
426            list(APPEND DOC_TARGETS latex)
427         endif()
428      endif()
429
430      # The doc target will build all documentation targets.
431      add_custom_target(doc)
432
433      foreach (DOC_TARGET ${DOC_TARGETS})
434         add_custom_target(${DOC_TARGET}
435            ${SPHINX_EXECUTABLE}
436            # -q   # Enable for quiet mode
437            -b ${DOC_TARGET}
438            -d "${SPHINX_CACHE_DIR}"
439            # -c "${BINARY_BUILD_DIR}" # enable if using cmake-generated conf.py
440            "${CMAKE_CURRENT_SOURCE_DIR}/doc"
441            "${CMAKE_CURRENT_BINARY_DIR}/doc/${DOC_TARGET}"
442            COMMENT "Building ${DOC_TARGET} documentation with Sphinx")
443
444         add_dependencies(doc ${DOC_TARGET})
445      endforeach()
446
447      message("Building documentation enabled for: ${DOC_TARGETS}")
448   endif()
449endif ()
450
451
452option(JANSSON_WITHOUT_TESTS "Don't build tests ('make test' to execute tests)" OFF)
453
454if (NOT JANSSON_WITHOUT_TESTS)
455   option(JANSSON_TEST_WITH_VALGRIND "Enable valgrind tests." OFF)
456
457   ENABLE_TESTING()
458
459   if (JANSSON_TEST_WITH_VALGRIND)
460      # TODO: Add FindValgrind.cmake instead of having a hardcoded path.
461
462      add_definitions(-DVALGRIND)
463
464      # enable valgrind
465      set(CMAKE_MEMORYCHECK_COMMAND valgrind)
466      set(CMAKE_MEMORYCHECK_COMMAND_OPTIONS
467         "--error-exitcode=1 --leak-check=full --show-reachable=yes --track-origins=yes -q")
468
469      set(MEMCHECK_COMMAND
470         "${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS}")
471      separate_arguments(MEMCHECK_COMMAND)
472   endif ()
473
474   #
475   # Test suites.
476   #
477   if (CMAKE_COMPILER_IS_GNUCC)
478      add_definitions(-Wall -Wextra -Wdeclaration-after-statement)
479   endif ()
480
481   set(api_tests
482         test_array
483         test_copy
484         test_dump
485         test_dump_callback
486         test_equal
487         test_load
488         test_loadb
489         test_number
490         test_object
491         test_pack
492         test_simple
493         test_unpack)
494
495   # Doing arithmetic on void pointers is not allowed by Microsofts compiler
496   # such as secure_malloc and secure_free is doing, so exclude it for now.
497   if (NOT MSVC)
498      list(APPEND api_tests test_memory_funcs)
499   endif()
500
501   # Helper macro for building and linking a test program.
502   macro(build_testprog name dir)
503       add_executable(${name} ${dir}/${name}.c)
504       add_dependencies(${name} jansson)
505       target_link_libraries(${name} jansson)
506   endmacro(build_testprog)
507
508   # Create executables and tests/valgrind tests for API tests.
509   foreach (test ${api_tests})
510      build_testprog(${test} ${PROJECT_SOURCE_DIR}/test/suites/api)
511
512      if (JANSSON_TEST_WITH_VALGRIND)
513         add_test(memcheck__${test}
514                  ${MEMCHECK_COMMAND} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test})
515      else()
516         add_test(${test} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test})
517      endif ()
518   endforeach ()
519
520   # Test harness for the suites tests.
521   build_testprog(json_process ${PROJECT_SOURCE_DIR}/test/bin)
522
523   set(SUITES encoding-flags valid invalid invalid-unicode)
524   foreach (SUITE ${SUITES})
525       file(GLOB TESTDIRS ${jansson_SOURCE_DIR}/test/suites/${SUITE}/*)
526
527       foreach (TESTDIR ${TESTDIRS})
528         if (IS_DIRECTORY ${TESTDIR})
529            get_filename_component(TNAME ${TESTDIR} NAME)
530
531            set(SUITE_TEST_CMD ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/json_process)
532
533            if (JANSSON_TEST_WITH_VALGRIND)
534               add_test(memcheck__${SUITE}__${TNAME}
535                        ${MEMCHECK_COMMAND} ${SUITE_TEST_CMD} ${TESTDIR})
536            else()
537               add_test(${SUITE}__${TNAME}
538                        ${SUITE_TEST_CMD} ${TESTDIR})
539            endif()
540
541            if ((${SUITE} STREQUAL "valid" OR ${SUITE} STREQUAL "invalid") AND NOT EXISTS ${TESTDIR}/nostrip)
542               if (JANSSON_TEST_WITH_VALGRIND)
543                  add_test(memcheck__${SUITE}__${TNAME}__strip
544                           ${MEMCHECK_COMMAND} ${SUITE_TEST_CMD} --strip ${TESTDIR})
545               else()
546                  add_test(${SUITE}__${TNAME}__strip
547                           ${SUITE_TEST_CMD} --strip ${TESTDIR})
548               endif()
549            endif ()
550         endif ()
551       endforeach ()
552   endforeach ()
553
554   add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
555                     DEPENDS json_process ${api_tests})
556endif ()
557
558#
559# Installation preparation.
560#
561
562# Allow the user to override installation directories.
563set(JANSSON_INSTALL_LIB_DIR       lib CACHE PATH "Installation directory for libraries")
564set(JANSSON_INSTALL_BIN_DIR       bin CACHE PATH "Installation directory for executables")
565set(JANSSON_INSTALL_INCLUDE_DIR   include CACHE PATH "Installation directory for header files")
566
567if(WIN32 AND NOT CYGWIN)
568  set(DEF_INSTALL_CMAKE_DIR cmake)
569else()
570  set(DEF_INSTALL_CMAKE_DIR lib/cmake/jansson)
571endif()
572
573set(JANSSON_INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files")
574
575# Make sure the paths are absolute.
576foreach(p LIB BIN INCLUDE CMAKE)
577    set(var JANSSON_INSTALL_${p}_DIR)
578    if(NOT IS_ABSOLUTE "${${var}}")
579        set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
580    endif()
581endforeach()
582
583# Export targets (This is used for other CMake projects to easily find the libraries and include files).
584export(TARGETS jansson
585        FILE "${PROJECT_BINARY_DIR}/JanssonTargets.cmake")
586export(PACKAGE jansson)
587
588# Generate the config file for the build-tree.
589set(JANSSON__INCLUDE_DIRS
590    "${PROJECT_SOURCE_DIR}/include"
591    "${PROJECT_BINARY_DIR}/include")
592set(JANSSON_INCLUDE_DIRS ${JANSSON__INCLUDE_DIRS} CACHE PATH "Jansson include directories")
593configure_file(${PROJECT_SOURCE_DIR}/cmake/JanssonConfig.cmake.in
594                ${PROJECT_BINARY_DIR}/JanssonConfig.cmake
595                @ONLY)
596
597# Generate the config file for the installation tree.
598file(RELATIVE_PATH
599    REL_INCLUDE_DIR
600    "${JANSSON_INSTALL_CMAKE_DIR}"
601    "${JANSSON_INSTALL_INCLUDE_DIR}") # Calculate the relative directory from the Cmake dir.
602
603# Note the EVENT_CMAKE_DIR is defined in JanssonConfig.cmake.in,
604# we escape it here so it's evaluated when it is included instead
605# so that the include dirs are given relative to where the
606# config file is located.
607set(JANSSON__INCLUDE_DIRS
608    "\${JANSSON_CMAKE_DIR}/${REL_INCLUDE_DIR}")
609configure_file(${PROJECT_SOURCE_DIR}/cmake/JanssonConfig.cmake.in
610                ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/JanssonConfig.cmake
611                @ONLY)
612
613# Generate version info for both build-tree and install-tree.
614configure_file(${PROJECT_SOURCE_DIR}/cmake/JanssonConfigVersion.cmake.in
615                ${PROJECT_BINARY_DIR}/JanssonConfigVersion.cmake
616                @ONLY)
617
618# Define the public headers.
619set_target_properties(jansson PROPERTIES PUBLIC_HEADER "${JANSSON_HDR_PUBLIC}")
620#TODO: fix this.
621
622# Create pkg-conf file.
623# (We use the same files as ./configure does, so we
624#  have to defined the same variables used there).
625set(prefix      ${CMAKE_INSTALL_PREFIX})
626set(exec_prefix ${CMAKE_INSTALL_PREFIX})
627set(libdir      ${CMAKE_INSTALL_PREFIX}/${JANSSON_INSTALL_LIB_DIR})
628set(VERSION     ${JANSSON_DISPLAY_VERSION})
629configure_file(${CMAKE_CURRENT_SOURCE_DIR}/jansson.pc.in
630               ${CMAKE_CURRENT_BINARY_DIR}/jansson.pc @ONLY)
631
632#
633# Install targets.
634#
635install(TARGETS jansson
636        EXPORT JanssonTargets
637        LIBRARY DESTINATION "${JANSSON_INSTALL_LIB_DIR}" COMPONENT lib
638        ARCHIVE DESTINATION "${JANSSON_INSTALL_LIB_DIR}" COMPONENT lib
639        RUNTIME DESTINATION "${JANSSON_INSTALL_BIN_DIR}" COMPONENT lib # Windows DLLs
640        PUBLIC_HEADER DESTINATION "${JANSSON_INSTALL_INCLUDE_DIR}" COMPONENT dev)
641
642# Install the pkg-config.
643install (FILES
644         ${CMAKE_CURRENT_BINARY_DIR}/jansson.pc
645         DESTINATION ${JANSSON_INSTALL_LIB_DIR}/pkgconfig COMPONENT dev)
646
647# Install the configs.
648install(FILES
649    ${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/JanssonConfig.cmake
650    ${PROJECT_BINARY_DIR}/JanssonConfigVersion.cmake
651    DESTINATION "${JANSSON_INSTALL_CMAKE_DIR}" COMPONENT dev)
652
653# Install exports for the install-tree.
654install(EXPORT JanssonTargets
655        DESTINATION "${JANSSON_INSTALL_CMAKE_DIR}" COMPONENT dev)
656
657# For use when simply using add_library from a parent project to build jansson.
658set(JANSSON_LIBRARIES jansson CACHE STRING "Jansson libraries")
659