diff options
Diffstat (limited to 'CMakeLists.txt')
-rw-r--r-- | CMakeLists.txt | 248 |
1 files changed, 121 insertions, 127 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 151e54ba..ae1f08f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,10 @@ # Default=false (build shared and static libs) # Takes precedence over STATIC_ONLY # +# -DENABLE_LTO_BUILD=[true|false] +# Build a link-time optimized version (requires gcc or clang) +# Default=false (do not build a link time optimized version) +# # -DGOBJECT_INTROSPECTION=[true|false] # Set to build GObject introspection "typelib" files # Requires GObject Introspection development package (version MIN_GOBJECT_INTROSPECTION) @@ -67,6 +71,7 @@ # Default=true # +# ## DO NOT USE IF YOU ARE AN END-USER. FOR THE DEVELOPERS ONLY!! ## Special CMake Options for Developers # # -DABI_DUMPER=[true|false] @@ -75,12 +80,18 @@ # # -DADDRESS_SANITIZER=[true|false] # Build with the address sanitizer (requires gcc or clang) +# Default=false # # -DTHREAD_SANITIZER=[true|false] # Build with the thread sanitizer (requires gcc or clang) +# Default=false +# +# -DUNDEFINED_SANITIZER=[true|false] +# Build with the undefined sanitizer (requires gcc or clang) +# Default=false # -cmake_minimum_required(VERSION 3.1.0) #first line, to shutup a cygwin warning +cmake_minimum_required(VERSION 3.11.0) #first line, to shutup a cygwin warning project(libical C) #CXX is optional for the bindings cmake_policy(SET CMP0003 NEW) @@ -95,11 +106,23 @@ if(POLICY CMP0074) endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Kitware/modules") #Include CMake capabilities +include(LibIcalMacrosInternal) include(FeatureSummary) +# Exit for blacklisted compilers that don't support necessary C standards +# MSVC++ < 2013 aka 1800 +set(BAD_C_MESSAGE "") +if(MSVC) + if(MSVC_VERSION LESS 1800) + set(BAD_C_MESSAGE "MSVC 2013 or higher") + endif() +endif() +if(BAD_C_MESSAGE) + message(FATAL_ERROR "\nSorry, ${BAD_C_MESSAGE} is required to build this software. Please retry using a modern C compiler that supports the C99 standard.") +endif() + # Enable the test harness enable_testing() @@ -112,7 +135,7 @@ endif() set(LIBICAL_LIB_MAJOR_VERSION "3") set(LIBICAL_LIB_MINOR_VERSION "0") -set(LIBICAL_LIB_PATCH_VERSION "12") +set(LIBICAL_LIB_PATCH_VERSION "95") set(LIBICAL_LIB_VERSION_STRING "${LIBICAL_LIB_MAJOR_VERSION}.${LIBICAL_LIB_MINOR_VERSION}.${LIBICAL_LIB_PATCH_VERSION}" ) @@ -144,22 +167,12 @@ add_feature_info( "build the C++ bindings. Requires a C++ compiler" ) -option(STATIC_ONLY "Build static libraries only.") -add_feature_info( - "Option STATIC_ONLY" - STATIC_ONLY - "build static libraries only" -) +libical_option(STATIC_ONLY "Build static libraries only." False) if(STATIC_ONLY) set(LIBRARY_TYPE STATIC) endif() -option(SHARED_ONLY "Build shared (dynamic) libraries only. Takes precedence over STATIC_ONLY") -add_feature_info( - "Option SHARED_ONLY" - SHARED_ONLY - "build shared libraries only" -) +libical_option(SHARED_ONLY "Build shared (dynamic) libraries only. Takes precedence over STATIC_ONLY." False) if(SHARED_ONLY) set(STATIC_ONLY False) set(LIBRARY_TYPE SHARED) @@ -195,9 +208,11 @@ endif() # libicu is highly recommended for RSCALE support # libicu can be found at http://www.icu-project.org -# RSCALE info at https://tools.ietf.org/html/rfc7529 -if(NOT "$ENV{ICU_BASE}" STREQUAL "") #support the old ICU_BASE env - set(ICU_ROOT $ENV{ICU_BASE}) +# RSCALE info at http://tools.ietf.org/html/rfc7529 +if(DEFINED ICU_BASE) #to make --warn-uninitialized happy + if(NOT "$ENV{ICU_BASE}" STREQUAL "") #support the old ICU_BASE env + set(ICU_ROOT $ENV{ICU_BASE}) + endif() endif() find_package(ICU COMPONENTS uc i18n) set_package_properties(ICU PROPERTIES @@ -229,7 +244,7 @@ if(ICU_FOUND) get_filename_component(ICU_EXEC ${ICU_MAKECONV_EXECUTABLE} DIRECTORY) else() message(FATAL_ERROR - "Unable locate the ICU runtime path. Is your ICU installation broken?") + "Unable to locate the ICU runtime path. Is your ICU installation broken?") endif() set(ICU_BINARY_DIR ${ICU_EXEC} CACHE STRING DOC "Runtime binaries directory for the ICU library") endif() @@ -254,12 +269,7 @@ endif() if(WIN32) if(MSVC) add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DYY_NO_UNISTD_H) - option(USE_32BIT_TIME_T "Build using a 32bit time_t (ignored unless building with MSVC on Windows).") - add_feature_info( - "Option USE_32BIT_TIME_T" - USE_32BIT_TIME_T - "build using 32-bit time_t" - ) + libical_option(USE_32BIT_TIME_T "Build using a 32bit time_t (ignored unless building with MSVC on Windows)." False) if(USE_32BIT_TIME_T) add_definitions(-D_USE_32BIT_TIME_T) endif() @@ -274,6 +284,7 @@ endif() # Use GNUInstallDirs include(GNUInstallDirs) +set(BIN_INSTALL_DIR ${CMAKE_INSTALL_BINDIR} CACHE STRING "User executables directory name" FORCE) set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING "Library directory name" FORCE) set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE STRING "Include directory name" FORCE) set(SHARE_INSTALL_DIR ${CMAKE_INSTALL_DATAROOTDIR} CACHE STRING "Share directory name") @@ -292,42 +303,32 @@ if(APPLE) set(CMAKE_INSTALL_NAME_DIR ${LIB_DESTINATION}) endif() -option(ICAL_ERRORS_ARE_FATAL "icalerror_* calls will abort instead of internally signaling an error.") -add_feature_info( - "Option ICAL_ERRORS_ARE_FATAL" - ICAL_ERRORS_ARE_FATAL - "icalerror_* calls will abort instead of internally signaling an error" -) +libical_option(ICAL_ERRORS_ARE_FATAL "icalerror_* calls will abort instead of internally signaling an error." False) if(ICAL_ERRORS_ARE_FATAL) set(ICAL_ERRORS_ARE_FATAL 1) else() set(ICAL_ERRORS_ARE_FATAL 0) endif() -option(ICAL_ALLOW_EMPTY_PROPERTIES "Prevent empty properties from being replaced with X-LIC-ERROR properties.") -add_feature_info( - "Option ICAL_ALLOW_EMPTY_PROPERTIES" - ICAL_ALLOW_EMPTY_PROPERTIES - "prevents empty properties from being replaced with X-LIC-ERROR properties" -) +libical_option(ICAL_ALLOW_EMPTY_PROPERTIES "Prevents empty properties from being replaced with X-LIC-ERROR properties." False) if(ICAL_ALLOW_EMPTY_PROPERTIES) set(ICAL_ALLOW_EMPTY_PROPERTIES 1) else() set(ICAL_ALLOW_EMPTY_PROPERTIES 0) endif() -option(USE_BUILTIN_TZDATA "(Careful) Build using libical's built-in timezone data, else use the system timezone data on non-Windows systems. ALWAYS true on Windows. Non-Windows users should know what they're doing if they choose not to use system provided timezone data. The libical project does not guarantee that the built-in timezone data is up-to-date.") +if(WIN32 OR WINCE) + set(DEF_USE_BUILTIN_TZDATA True) +else() + set(DEF_USE_BUILTIN_TZDATA False) +endif() +libical_option(USE_BUILTIN_TZDATA "(Careful) Build using libical's built-in timezone data, else use the system timezone data on non-Windows systems. ALWAYS true on Windows. Non-Windows users should know what they're doing if they choose not to use system provided timezone data. The libical project does not guarantee that the built-in timezone data is up-to-date." ${DEF_USE_BUILTIN_TZDATA}) mark_as_advanced(USE_BUILTIN_TZDATA) if(USE_BUILTIN_TZDATA) set(USE_BUILTIN_TZDATA 1) else() set(USE_BUILTIN_TZDATA 0) endif() -add_feature_info( - "Option USE_BUILTIN_TZDATA" - USE_BUILTIN_TZDATA - "use our own timezone data rather then the system timezone data" -) if(WIN32 OR WINCE) #Always use builtin tzdata on Windows systems. if(NOT USE_BUILTIN_TZDATA) @@ -354,12 +355,7 @@ set(INSTALL_TARGETS_DEFAULT_ARGS find_package(PkgConfig QUIET) set(MIN_GOBJECT_INTROSPECTION "0.6.7") -option(GOBJECT_INTROSPECTION "Build GObject introspection \"typelib\" files. Requires GObject Introspection development package ${MIN_GOBJECT_INTROSPECTION} or higher.") -add_feature_info( - "Option GOBJECT_INTROSPECTION" - GOBJECT_INTROSPECTION - "build GObject introspection \"typelib\" files" -) +libical_option(GOBJECT_INTROSPECTION "Build GObject introspection \"typelib\" files. Requires GObject Introspection development package ${MIN_GOBJECT_INTROSPECTION} or higher." False) if(GOBJECT_INTROSPECTION) if(NOT PKG_CONFIG_FOUND) message(FATAL_ERROR @@ -392,19 +388,7 @@ if(GOBJECT_INTROSPECTION) endif() endif() -option(ICAL_BUILD_DOCS "Build documentation" True) -add_feature_info( - "Option ICAL_BUILD_DOCS" - ICAL_BUILD_DOCS - "build API documentation and reference manual" -) - -option(ICAL_GLIB_VAPI "Build Vala \"vapi\" files.") -add_feature_info( - "Option ICAL_GLIB_VAPI" - ICAL_GLIB_VAPI - "build Vala \"vapi\" files" -) +libical_option(ICAL_GLIB_VAPI "Build Vala \"vapi\" files." False) if(ICAL_GLIB_VAPI) if(NOT GOBJECT_INTROSPECTION) message(FATAL_ERROR @@ -427,14 +411,9 @@ if(ICAL_GLIB_VAPI) endif() endif() -set(MIN_GLIB "2.32") +set(MIN_GLIB "2.44") set(MIN_LIBXML "2.7.3") -option(ICAL_GLIB "Build libical-glib interface. Requires glib ${MIN_GLIB} and libxml ${MIN_LIBXML} development packages or higher." True) -add_feature_info( - "Option ICAL_GLIB" - ICAL_GLIB - "build libical-glib interface" -) +libical_option(ICAL_GLIB "Build libical-glib interface. Requires glib ${MIN_GLIB} and libxml ${MIN_LIBXML} development packages or higher." True) if(ICAL_GLIB) if(NOT PKG_CONFIG_FOUND) message(FATAL_ERROR @@ -480,28 +459,12 @@ endif() # Compiler settings # if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" MATCHES "Clang") - include(CheckCCompilerFlag) - check_c_compiler_flag(-Wunused-but-set-variable HAVE_GCC_UNUSED_BUT_SET) - check_c_compiler_flag(-Wlogical-op HAVE_GCC_LOGICAL_OP) - check_c_compiler_flag(-Wsizeof-pointer-memaccess HAVE_GCC_POINTER_MEMACCESS) - check_c_compiler_flag(-Wformat-security HAVE_GCC_FORMAT_SECURITY) - check_c_compiler_flag(-Wredundant-decls HAVE_GCC_REDUNDANT_DECLS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -Wno-deprecated -Wall -Wno-unknown-pragmas -Wextra -Winit-self -Wunused -Wno-div-by-zero -Wundef -Wpointer-arith -Wtype-limits -Wwrite-strings -Werror=return-type") - if(HAVE_GCC_UNUSED_BUT_SET) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused-but-set-variable") - endif() - if(HAVE_GCC_LOGICAL_OP) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wlogical-op") - endif() - if(HAVE_GCC_POINTER_MEMACCESS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsizeof-pointer-memaccess") - endif() - if(HAVE_GCC_FORMAT_SECURITY) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat -Wformat-security") - endif() - if(HAVE_GCC_REDUNDANT_DECLS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wredundant-decls") - endif() + libical_add_cflag(-Wunused-but-set-variable UNUSED_BUT_SET) + libical_add_cflag(-Wlogical-op LOGICAL_OP) + libical_add_cflag(-Wsizeof-pointer-memaccess POINTER_MEMACCESS) + libical_add_cflag(-Wformat-security FORMAT_SECURITY) + libical_add_cflag(-Wredundant-decls REDUNDANT_DECLS) if(CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME STREQUAL GNU) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -D_GNU_SOURCE") endif() @@ -511,32 +474,13 @@ if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") endif() if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag(-Wunused-but-set-variable HAVE_GXX_UNUSED_BUT_SET) - check_cxx_compiler_flag(-Wlogical-op HAVE_GXX_LOGICAL_OP) - check_cxx_compiler_flag(-Wsizeof-pointer-memaccess HAVE_GXX_POINTER_MEMACCESS) - check_cxx_compiler_flag(-Wreorder HAVE_GXX_REORDER) - check_cxx_compiler_flag(-Wformat-security HAVE_GXX_FORMAT_SECURITY) - check_cxx_compiler_flag(-Wredundant-decls HAVE_GXX_REDUNDANT_DECLS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Weffc++ -Wno-deprecated -Wall -Wextra -Woverloaded-virtual -Winit-self -Wunused -Wno-div-by-zero -Wundef -Wpointer-arith -Wtype-limits -Wwrite-strings -Werror=return-type") - if(HAVE_GXX_UNUSED_BUT_SET) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-but-set-variable") - endif() - if(HAVE_GXX_LOGICAL_OP) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wlogical-op") - endif() - if(HAVE_GXX_POINTER_MEMACCESS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsizeof-pointer-memaccess") - endif() - if(HAVE_GXX_REORDER) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wreorder") - endif() - if(HAVE_GXX_FORMAT_SECURITY) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security") - endif() - if(HAVE_GXX_REDUNDANT_DECLS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wredundant-decls") - endif() + libical_add_cxxflag(-Wunused-but-set-variable UNUSED_BUT_SET) + libical_add_cxxflag(-Wlogical-op LOGICAL_OP) + libical_add_cxxflag(-Wsizeof-pointer-memaccess POINTER_MEMACCESS) + libical_add_cxxflag(-Wreorder REORDER) + libical_add_cxxflag(-Wformat-security FORMAT_SECURITY) + libical_add_cxxflag(-Wredundant-decls REDUNDANT_DECLS) if(CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME STREQUAL GNU) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -D_GNU_SOURCE") endif() @@ -545,8 +489,13 @@ if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments") endif() +#some test programs need to know if we are using 32-bit time +if(SIZEOF_TIME_T EQUAL 4) + set(USE_32BIT_TIME_T TRUE) +endif() + ################ Developer Options ##################### -option(ABI_DUMPER "(Developer-only) Build for abi-dumper." False) +libical_option(ABI_DUMPER "(Developer-only) Build for abi-dumper." False) mark_as_advanced(ABI_DUMPER) if(ABI_DUMPER) if(CMAKE_COMPILER_IS_GNUCC) @@ -558,7 +507,7 @@ if(ABI_DUMPER) endif() endif() -option(ADDRESS_SANITIZER "(Developer-only) Build with the address sanitizer." False) +libical_option(ADDRESS_SANITIZER "(Developer-only) Build with the address sanitizer." False) mark_as_advanced(ADDRESS_SANITIZER) if(ADDRESS_SANITIZER) if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" MATCHES "Clang") @@ -584,7 +533,7 @@ if(ADDRESS_SANITIZER) endif() endif() -option(THREAD_SANITIZER "(Developer-only) Build with the thread sanitizer." False) +libical_option(THREAD_SANITIZER "(Developer-only) Build with the thread sanitizer." False) mark_as_advanced(THREAD_SANITIZER) if(THREAD_SANITIZER) if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" MATCHES "Clang") @@ -610,17 +559,61 @@ if(THREAD_SANITIZER) endif() endif() -#some test programs need to know if we are using 32-bit time -if(SIZEOF_TIME_T EQUAL 4) - set(USE_32BIT_TIME_T TRUE) +libical_option(UNDEFINED_SANITIZER "(Developer-only) Build with the undefined sanitizer." False) +mark_as_advanced(UNDEFINED_SANITIZER) +if(UNDEFINED_SANITIZER) + if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -O1 -g -DUNDEFINED_SANITIZER -lubsan") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -O1 -g -DUNDEFINED_SANITIZER -lubsan") + else() + message(FATAL_ERROR + "You are trying to build with the undefined sanitizer using a non-GCC or Clang compiler.") + endif() + if(GOBJECT_INTROSPECTION) + message(STATUS + "Warning: Building the undefined sanitizer with GObject Introspection is is not supported. " + "Turning-off GObject Introspection." + ) + set(HAVE_INTROSPECTION False) + endif() + if(ICAL_GLIB) + message(STATUS + "Warning: Building the undefined sanitizer with the GObject interface is not supported. " + "Turning-off the GObject interface." + ) + set(ICAL_GLIB False) + endif() endif() -option(LIBICAL_BUILD_TESTING "Build tests." True) -add_feature_info( - "Option LIBICAL_BUILD_TESTING" - LIBICAL_BUILD_TESTING - "build tests" -) +libical_option(ENABLE_LTO_BUILD "Build a link-time optimized version." False) +if(ENABLE_LTO_BUILD) + if(CMAKE_COMPILER_IS_GNUCC) + libical_add_cflag(-flto LTO) + if(C_SUPPORTS_LTO) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wlto-type-mismatch -fuse-linker-plugin") + set(CMAKE_AR "gcc-ar") + set(CMAKE_RANLIB "gcc-ranlib") + else() + message(FATAL_ERROR + "Your C compiler ${CMAKE_C_COMPILER_ID} does not support the LTO building.") + endif() + if(WITH_CXX_BINDINGS AND CMAKE_COMPILER_IS_GNUCXX) + include(CheckCXXCompilerFlag) + libical_add_cxxflag(-flto LTO) + if(CXX_SUPPORTS_LTO) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wlto-type-mismatch -fuse-linker-plugin") + else() + message(FATAL_ERROR + "Your C++ compiler ${CMAKE_CXX_COMPILER_ID} does not support LTO building.") + endif() + endif() + else() + message(FATAL_ERROR + "Build link-time optimization using a non-GCC compiler is currently not supported.") + endif() +endif() + +libical_option(LIBICAL_BUILD_TESTING "Build tests." True) ################# build subdirs ######################## @@ -634,6 +627,7 @@ if(USE_BUILTIN_TZDATA) add_subdirectory(zoneinfo) endif() +libical_option(ICAL_BUILD_DOCS "Build documentation" True) if(ICAL_BUILD_DOCS) add_subdirectory(doc) # needs to go last, for the build source files endif() |