Merge remote-tracking branch 'google/develop' into release
[platform/upstream/gflags.git] / CMakeLists.txt
1 cmake_minimum_required (VERSION 2.8.4 FATAL_ERROR)
2
3 # ----------------------------------------------------------------------------
4 # includes
5 set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
6 include (utils)
7
8 # ----------------------------------------------------------------------------
9 # package information
10 set (PACKAGE_NAME      "gflags")
11 set (PACKAGE_VERSION   "2.1.0")
12 set (PACKAGE_STRING    "${PACKAGE_NAME} ${PACKAGE_VERSION}")
13 set (PACKAGE_TARNAME   "${PACKAGE_NAME}-${PACKAGE_VERSION}")
14 set (PACKAGE_BUGREPORT "https://code.google.com/p/gflags/issues/")
15
16 project (${PACKAGE_NAME} CXX)
17
18 version_numbers (
19   ${PACKAGE_VERSION}
20     PACKAGE_VERSION_MAJOR
21     PACKAGE_VERSION_MINOR
22     PACKAGE_VERSION_PATCH
23 )
24
25 # ----------------------------------------------------------------------------
26 # options
27 set (GFLAGS_NAMESPACE   "${PACKAGE_NAME}" CACHE STRING "C++ namespace identifier of gflags library.")
28 set (GFLAGS_INCLUDE_DIR "${PACKAGE_NAME}" CACHE STRING "Include subdirectory of gflags header files.")
29
30 if (IS_ABSOLUTE GFLAGS_INCLUDE_DIR)
31   message (FATAL_ERROR "GFLAGS_INCLUDE_DIR must be a path relative to CMAKE_INSTALL_PREFIX/include")
32 endif ()
33 if (GFLAGS_INCLUDE_DIR MATCHES "^\\.\\.[/\\]")
34   message (FATAL_ERROR "GFLAGS_INCLUDE_DIR must not start with parent directory reference (../)")
35 endif ()
36
37 option (BUILD_SHARED_LIBS          "Request build of shared libraries."                                       OFF)
38 option (BUILD_STATIC_LIBS          "Request build of static libraries (default if BUILD_SHARED_LIBS is OFF)." OFF)
39 option (BUILD_gflags_LIB           "Request build of the multi-threaded gflags library."                      ON)
40 option (BUILD_gflags_nothreads_LIB "Request build of the single-threaded gflags library."                     ON)
41 option (BUILD_PACKAGING            "Enable build of distribution packages using CPack."                       OFF)
42 option (BUILD_TESTING              "Enable build of the unit tests and their execution using CTest."          OFF)
43 option (BUILD_NC_TESTS             "Request addition of negative compilation tests."                          OFF)
44 option (INSTALL_HEADERS            "Request packaging of headers and other development files."                ON)
45
46 mark_as_advanced (CLEAR CMAKE_INSTALL_PREFIX)
47 mark_as_advanced (CMAKE_CONFIGURATION_TYPES
48                   GFLAGS_NAMESPACE
49                   GFLAGS_INCLUDE_DIR
50                   BUILD_STATIC_LIBS
51                   BUILD_NC_TESTS
52                   INSTALL_HEADERS)
53 if (APPLE)
54   mark_as_advanced(CMAKE_OSX_ARCHITECTURES
55                    CMAKE_OSX_DEPLOYMENT_TARGET
56                    CMAKE_OSX_SYSROOT)
57 endif ()
58
59 if (NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
60   set (BUILD_STATIC_LIBS ON)
61 endif ()
62 if (NOT BUILD_gflags_LIB AND NOT BUILD_gflags_nothreads_LIB)
63  message (FATAL_ERROR "At least one of BUILD_gflags_LIB and BUILD_gflags_nothreads_LIB must be ON.")
64 endif ()
65
66 if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS)
67   set_property (CACHE CMAKE_BUILD_TYPE PROPERTY VALUE Release)
68 endif ()
69
70 # ----------------------------------------------------------------------------
71 # system checks
72 include (CheckTypeSize)
73 include (CheckIncludeFileCXX)
74 include (CheckCXXSymbolExists)
75
76 if (WIN32 AND NOT CYGWIN)
77   set (OS_WINDOWS 1)
78 else ()
79   set (OS_WINDOWS 0)
80 endif ()
81
82 if (MSVC)
83   set (HAVE_SYS_TYPES_H 1)
84   set (HAVE_STDINT_H    1)
85   set (HAVE_STDDEF_H    1) # used by CheckTypeSize module
86   set (HAVE_INTTYPES_H  0)
87   set (HAVE_UNISTD_H    0)
88   set (HAVE_SYS_STAT_H  1)
89   set (HAVE_SHLWAPI_H   1)
90 else ()
91   foreach (fname IN ITEMS unistd stdint inttypes sys/types sys/stat fnmatch)
92     string (TOUPPER "${fname}" FNAME)
93     string (REPLACE "/" "_" FNAME "${FNAME}")
94     if (NOT HAVE_${FNAME}_H)
95       check_include_file_cxx ("${fname}.h" HAVE_${FNAME}_H)
96     endif ()
97   endforeach ()
98   # the following are used in #if directives not #ifdef
99   bool_to_int (HAVE_STDINT_H)
100   bool_to_int (HAVE_SYS_TYPES_H)
101   bool_to_int (HAVE_INTTYPES_H)
102   if (NOT HAVE_FNMATCH_H AND OS_WINDOWS)
103     check_include_file_cxx ("shlwapi.h" HAVE_SHLWAPI_H)
104   endif ()
105 endif ()
106
107 set (GFLAGS_INTTYPES_FORMAT "" CACHE STRING "Format of integer types: \"C99\" (uint32_t), \"BSD\" (u_int32_t), \"VC7\" (__int32)")
108 set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY STRINGS "C99;BSD;VC7")
109 mark_as_advanced (GFLAGS_INTTYPES_FORMAT)
110 if (NOT GFLAGS_INTTYPES_FORMAT)
111   set (TYPES uint32_t u_int32_t)
112   if (MSVC)
113     list (INSERT TYPES 0 __int32)
114   endif ()
115   foreach (type IN LISTS TYPES)
116     check_type_size (${type} ${type} LANGUAGE CXX)
117     if (HAVE_${type})
118       break ()
119     endif ()
120   endforeach ()
121   if (HAVE_uint32_t)
122     set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY VALUE C99)
123   elseif (HAVE_u_int32_t)
124     set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY VALUE BSD)
125   elseif (HAVE___int32)
126     set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY VALUE VC7)
127   else ()
128     mark_as_advanced (CLEAR GFLAGS_INTTYPES_FORMAT)
129     message (FATAL_ERROR "Do not know how to define a 32-bit integer quantity on your system!"
130                          " Neither uint32_t, u_int32_t, nor __int32 seem to be available."
131                          " Set GFLAGS_INTTYPES_FORMAT to either C99, BSD, or VC7 and try again.")
132   endif ()
133 endif ()
134 # use of special characters in strings to circumvent bug #0008226
135 if ("^${GFLAGS_INTTYPES_FORMAT}$" STREQUAL "^WIN$")
136   set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY VALUE VC7)
137 endif ()
138 if (NOT GFLAGS_INTTYPES_FORMAT MATCHES "^(C99|BSD|VC7)$")
139   message (FATAL_ERROR "Invalid value for GFLAGS_INTTYPES_FORMAT! Choose one of \"C99\", \"BSD\", or \"VC7\"")
140 endif ()
141 set (GFLAGS_INTTYPES_FORMAT_C99 0)
142 set (GFLAGS_INTTYPES_FORMAT_BSD 0)
143 set (GFLAGS_INTTYPES_FORMAT_VC7 0)
144 set ("GFLAGS_INTTYPES_FORMAT_${GFLAGS_INTTYPES_FORMAT}" 1)
145
146 if (MSVC)
147   set (HAVE_strtoll 0)
148   set (HAVE_strtoq  0)
149 else ()
150   check_cxx_symbol_exists (strtoll stdlib.h HAVE_STRTOLL)
151   if (NOT HAVE_STRTOLL)
152     check_cxx_symbol_exists (strtoq stdlib.h HAVE_STRTOQ)
153   endif ()
154 endif ()
155
156 set (CMAKE_THREAD_PREFER_PTHREAD TRUE)
157 find_package (ThreadsCXX)
158 if (Threads_FOUND AND CMAKE_USE_PTHREADS_INIT)
159   set (HAVE_PTHREAD 1)
160   check_type_size (pthread_rwlock_t RWLOCK LANGUAGE CXX)
161 else ()
162   set (HAVE_PTHREAD 0)
163 endif ()
164
165 if (UNIX AND NOT HAVE_PTHREAD AND BUILD_gflags_LIB)
166   if (CMAKE_HAVE_PTHREAD_H)
167     set (what "library")
168   else ()
169     set (what ".h file")
170   endif ()
171   message (FATAL_ERROR "Could not find pthread${what}. Check the log file"
172                        "\n\t${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
173                        "\nor disable the build of the multi-threaded gflags library (BUILD_gflags_LIB=OFF).")
174 endif ()
175
176 # ----------------------------------------------------------------------------
177 # source files - excluding root subdirectory and/or .in suffix
178 set (PUBLIC_HDRS
179   "gflags.h"
180   "gflags_declare.h"
181   "gflags_completions.h"
182 )
183
184 set (PRIVATE_HDRS
185   "config.h"
186   "util.h"
187   "mutex.h"
188 )
189
190 set (GFLAGS_SRCS
191   "gflags.cc"
192   "gflags_reporting.cc"
193   "gflags_completions.cc"
194 )
195
196 if (OS_WINDOWS)
197   list (APPEND PRIVATE_HDRS "windows_port.h")
198   list (APPEND GFLAGS_SRCS  "windows_port.cc")
199 endif ()
200
201 # ----------------------------------------------------------------------------
202 # configure source files
203 if (CMAKE_COMPILER_IS_GNUCXX)
204   set (GFLAGS_ATTRIBUTE_UNUSED "__attribute((unused))")
205 else ()
206   set (GFLAGS_ATTRIBUTE_UNUSED)
207 endif ()
208
209 # whenever we build a shared library (DLL on Windows), configure the public
210 # headers of the API for use of this library rather than the optionally
211 # also build statically linked library; users can override GFLAGS_DLL_DECL
212 if (BUILD_SHARED_LIBS)
213   set (GFLAGS_IS_A_DLL 1)
214 else ()
215   set (GFLAGS_IS_A_DLL 0)
216 endif ()
217
218 configure_headers (PUBLIC_HDRS  ${PUBLIC_HDRS})
219 configure_sources (PRIVATE_HDRS ${PRIVATE_HDRS})
220 configure_sources (GFLAGS_SRCS  ${GFLAGS_SRCS})
221
222 include_directories ("${PROJECT_SOURCE_DIR}/src")
223 include_directories ("${PROJECT_BINARY_DIR}/include")
224 include_directories ("${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}")
225
226 # ----------------------------------------------------------------------------
227 # output directories
228 set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin")
229 set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "lib")
230 set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "lib")
231
232 # ----------------------------------------------------------------------------
233 # add library targets
234 set (TARGETS)
235 # static vs. shared
236 foreach (TYPE IN ITEMS STATIC SHARED)
237   if (BUILD_${TYPE}_LIBS)
238     # whether or not targets are a DLL
239     if (OS_WINDOWS AND "^${TYPE}$" STREQUAL "^SHARED$")
240       set (GFLAGS_IS_A_DLL 1)
241     else ()
242       set (GFLAGS_IS_A_DLL 0)
243     endif ()
244     string (TOLOWER "${TYPE}" type)
245     # multi-threaded vs. single-threaded
246     foreach (opts IN ITEMS "" _nothreads)
247       if (BUILD_gflags${opts}_LIB)
248         add_library (gflags${opts}-${type} ${TYPE} ${GFLAGS_SRCS} ${PRIVATE_HDRS} ${PUBLIC_HDRS})
249         if (opts MATCHES "nothreads")
250           set (defines "GFLAGS_IS_A_DLL=${GFLAGS_IS_A_DLL};NOTHREADS")
251         else ()
252           set (defines "GFLAGS_IS_A_DLL=${GFLAGS_IS_A_DLL}")
253           if (CMAKE_USE_PTHREADS_INIT)
254             target_link_libraries (gflags${opts}-${type} ${CMAKE_THREAD_LIBS_INIT})
255           endif ()
256         endif ()
257         set_target_properties (
258           gflags${opts}-${type} PROPERTIES COMPILE_DEFINITIONS "${defines}"
259                                            OUTPUT_NAME "gflags${opts}"
260         )
261         if (HAVE_SHLWAPI_H)
262           target_link_libraries (gflags${opts}-${type} shlwapi.lib)
263         endif ()
264         if (NOT TARGET gflags${opts})
265           add_custom_target (gflags${opts})
266         endif ()
267         add_dependencies (gflags${opts} gflags${opts}-${type})
268         list (APPEND TARGETS gflags${opts}-${type})
269       endif ()
270     endforeach ()
271   endif ()
272 endforeach ()
273
274 # ----------------------------------------------------------------------------
275 # installation
276 if (OS_WINDOWS)
277   set (RUNTIME_INSTALL_DIR Bin)
278   set (LIBRARY_INSTALL_DIR Lib)
279   set (INCLUDE_INSTALL_DIR Include)
280   set (CONFIG_INSTALL_DIR  CMake)
281 else ()
282   set (RUNTIME_INSTALL_DIR bin)
283   set (LIBRARY_INSTALL_DIR lib)
284   set (INCLUDE_INSTALL_DIR include)
285   set (CONFIG_INSTALL_DIR  lib/cmake/${PACKAGE_NAME})
286 endif ()
287
288 file (RELATIVE_PATH INSTALL_PREFIX_REL2CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/${CONFIG_INSTALL_DIR}" "${CMAKE_INSTALL_PREFIX}")
289 configure_file (cmake/config.cmake.in  "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config-install.cmake" @ONLY)
290 configure_file (cmake/version.cmake.in "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake" @ONLY)
291
292 install (TARGETS ${TARGETS} DESTINATION ${LIBRARY_INSTALL_DIR} EXPORT gflags-lib)
293 if (INSTALL_HEADERS)
294   install (FILES ${PUBLIC_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/${GFLAGS_INCLUDE_DIR})
295   install (
296     FILES "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config-install.cmake"
297     RENAME ${PACKAGE_NAME}-config.cmake
298     DESTINATION ${CONFIG_INSTALL_DIR}
299   )
300   install (
301     FILES "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake"
302     DESTINATION ${CONFIG_INSTALL_DIR}
303   )
304   install (EXPORT gflags-lib DESTINATION ${CONFIG_INSTALL_DIR} FILE ${PACKAGE_NAME}-export.cmake)
305   if (UNIX)
306     install (PROGRAMS src/gflags_completions.sh DESTINATION ${RUNTIME_INSTALL_DIR})
307   endif ()
308 endif ()
309
310 # ----------------------------------------------------------------------------
311 # support direct use of build tree
312 set (INSTALL_PREFIX_REL2CONFIG_DIR .)
313 export (TARGETS ${TARGETS} FILE "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-export.cmake")
314 export (PACKAGE gflags)
315 configure_file (cmake/config.cmake.in "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config.cmake" @ONLY)
316
317 # ----------------------------------------------------------------------------
318 # testing - MUST follow the generation of the build tree config file
319 if (BUILD_TESTING)
320   include (CTest)
321   enable_testing ()
322   add_subdirectory (test)
323 endif ()
324
325 # ----------------------------------------------------------------------------
326 # packaging
327 if (BUILD_PACKAGING)
328
329   if (NOT BUILD_SHARED_LIBS AND NOT INSTALL_HEADERS)
330     message (WARNING "Package will contain static libraries without headers!"
331                      "\nRecommended options for generation of runtime package:"
332                      "\n  BUILD_SHARED_LIBS=ON"
333                      "\n  BUILD_STATIC_LIBS=OFF"
334                      "\n  INSTALL_HEADERS=OFF"
335                      "\nRecommended options for generation of development package:"
336                      "\n  BUILD_SHARED_LIBS=ON"
337                      "\n  BUILD_STATIC_LIBS=ON"
338                      "\n  INSTALL_HEADERS=ON")
339   endif ()
340
341   # default package generators
342   if (APPLE)
343     set (PACKAGE_GENERATOR        "PackageMaker")
344     set (PACKAGE_SOURCE_GENERATOR "TGZ;ZIP")
345   elseif (UNIX)
346     set (PACKAGE_GENERATOR        "DEB;RPM")
347     set (PACKAGE_SOURCE_GENERATOR "TGZ;ZIP")
348   else ()
349     set (PACKAGE_GENERATOR        "ZIP")
350     set (PACKAGE_SOURCE_GENERATOR "ZIP")
351   endif ()
352
353   # used package generators
354   set (CPACK_GENERATOR        "${PACKAGE_GENERATOR}"        CACHE STRING "List of binary package generators (CPack).")
355   set (CPACK_SOURCE_GENERATOR "${PACKAGE_SOURCE_GENERATOR}" CACHE STRING "List of source package generators (CPack).")
356   mark_as_advanced (CPACK_GENERATOR CPACK_SOURCE_GENERATOR)
357
358   # common package information
359   set (CPACK_PACKAGE_VENDOR              "Andreas Schuh")
360   set (CPACK_PACKAGE_CONTACT             "google-gflags@googlegroups.com")
361   set (CPACK_PACKAGE_NAME                "${PACKAGE_NAME}")
362   set (CPACK_PACKAGE_VERSION             "${PACKAGE_VERSION}")
363   set (CPACK_PACKAGE_VERSION_MAJOR       "${PACKAGE_VERSION_MAJOR}")
364   set (CPACK_PACKAGE_VERSION_MINOR       "${PACKAGE_VERSION_MINOR}")
365   set (CPACK_PACKAGE_VERSION_PATCH       "${PACKAGE_VERSION_PATCH}")
366   set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "A commandline flags library that allows for distributed flags.")
367   set (CPACK_RESOURCE_FILE_WELCOME       "${CMAKE_CURRENT_LIST_DIR}/README.txt")
368   set (CPACK_RESOURCE_FILE_LICENSE       "${CMAKE_CURRENT_LIST_DIR}/COPYING.txt")
369   set (CPACK_PACKAGE_DESCRIPTION_FILE    "${CMAKE_CURRENT_LIST_DIR}/README.txt")
370   set (CPACK_INSTALL_PREFIX              "${CMAKE_INSTALL_PREFIX}")
371   set (CPACK_OUTPUT_FILE_PREFIX          packages)
372   set (CPACK_PACKAGE_RELOCATABLE         TRUE)
373   set (CPACK_MONOLITHIC_INSTALL          TRUE)
374
375   # RPM package information -- used in cmake/package.cmake.in also for DEB
376   set (CPACK_RPM_PACKAGE_GROUP   "Development/Libraries")
377   set (CPACK_RPM_PACKAGE_LICENSE "BSD")
378   set (CPACK_RPM_PACKAGE_URL     "http://code.google.com/p/gflags")
379   set (CPACK_RPM_CHANGELOG_FILE  "${CMAKE_CURRENT_LIST_DIR}/ChangeLog.txt")
380
381   if (INSTALL_HEADERS)
382     set (CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_LIST_DIR}/doc/gflags.html")
383   else ()
384     set (CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_LIST_DIR}/cmake/README_runtime.txt")
385   endif ()
386
387   # system/architecture
388   if (WINDOWS)
389     if (CMAKE_CL_64)
390       set (CPACK_SYSTEM_NAME "win64")
391     else ()
392       set (CPACK_SYSTEM_NAME "win32")
393     endif ()
394     set (CPACK_PACKAGE_ARCHITECTURE)
395   else ()
396     string (TOLOWER "${CMAKE_SYSTEM_NAME}" CPACK_SYSTEM_NAME)
397     if (CMAKE_CXX_FLAGS MATCHES "-m32")
398       set (CPACK_PACKAGE_ARCHITECTURE i386)
399     else ()
400       execute_process (
401         COMMAND         dpkg --print-architecture
402         RESULT_VARIABLE RV
403         OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE
404       )
405       if (RV EQUAL 0)
406               string (STRIP "${CPACK_PACKAGE_ARCHITECTURE}" CPACK_PACKAGE_ARCHITECTURE)
407       else ()
408         execute_process (COMMAND uname -m OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE)
409         if (CPACK_PACKAGE_ARCHITECTURE MATCHES "x86_64")
410                 set (CPACK_PACKAGE_ARCHITECTURE amd64)
411         else ()
412           set (CPACK_PACKAGE_ARCHITECTURE i386)
413         endif ()
414       endif ()
415     endif ()
416   endif ()
417
418   # source package settings
419   set (CPACK_SOURCE_TOPLEVEL_TAG      "source")
420   set (CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
421   set (CPACK_SOURCE_IGNORE_FILES      "/\\\\.git/;\\\\.swp$;\\\\.#;/#;\\\\.*~;cscope\\\\.*;/[Bb]uild[.+-_a-zA-Z0-9]*/")
422
423   # default binary package settings
424   set (CPACK_INCLUDE_TOPLEVEL_DIRECTORY TRUE)
425   set (CPACK_PACKAGE_FILE_NAME          "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}")
426   if (CPACK_PACKAGE_ARCHITECTURE)
427     set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CPACK_PACKAGE_ARCHITECTURE}")
428   endif ()
429
430   # generator specific configuration file
431   #
432   # allow package maintainers to use their own configuration file
433   # $ cmake -DCPACK_PROJECT_CONFIG_FILE:FILE=/path/to/package/config
434   if (NOT CPACK_PROJECT_CONFIG_FILE)
435     configure_file (
436       "${CMAKE_CURRENT_LIST_DIR}/cmake/package.cmake.in"
437       "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-package.cmake" @ONLY
438     )
439     set (CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-package.cmake")
440   endif ()
441
442   include (CPack)
443
444 endif () # BUILD_PACKAGING