take review comments into account * protect GCC-specific stuff * use `list(APPEND...)` * use CMake-style way to choose whether LTO should/can be done or not * only install public header, not all * add correct `install` option for DLL's on Windows * use correct folder for .pc files * check if `uname` exists & add support for FreeBSD Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b36718c..1b98776 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,7 +21,11 @@ set(PACKAGE_RELEASE_VERSION 1)
# Include cmake modules
#-----------------------------------------------------------------------------
include(GNUInstallDirs)
+include(CheckIPOSupported)
include(CMakePackageConfigHelpers)
+# default is "No tests"
+option(BUILD_TESTING "" OFF)
+include(CTest)
include(sources.cmake)
# The only direct cmake argument for now
@@ -31,42 +35,41 @@ option(BUILD_SHARED_LIBS "Build shared library and only the shared library if \"
# Compose CFLAGS
#-----------------------------------------------------------------------------
-# Some information copied from makefile_include.mk
+# Some information ported from makefile_include.mk
-# Basic set
-set(LTM_C_FLAGS -Wall -Wsign-compare -Wextra -Wshadow)
-set(LTM_C_FLAGS ${LTM_C_FLAGS} -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align)
-set(LTM_C_FLAGS ${LTM_C_FLAGS} -Wstrict-prototypes -Wpointer-arith -Wsystem-headers)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE "Release")
endif()
-set(CMAKE_C_FLAGS_DEBUG "-g3")
-set(CMAKE_C_FLAGS_RELEASE "-O3 -funroll-loops -fomit-frame-pointer")
-set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g3 -O2")
-set(CMAKE_C_FLAGS_MINSIZEREL "-Os")
-
-if(COMPILE_LTO)
- set(LTM_C_FLAGS ${LTM_C_FLAGS} -flto)
- set(LTM_LD_FLAGS ${LTM_LD_FLAGS} -flto)
+# We only differentiate between MSVC and GCC-compatible compilers
+if(MSVC)
+ set(LTM_C_FLAGS -W3)
+else()
+ set(LTM_C_FLAGS -Wall -Wsign-compare -Wextra -Wshadow
+ -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align
+ -Wstrict-prototypes -Wpointer-arith -Wsystem-headers)
+ set(CMAKE_C_FLAGS_DEBUG "-g3")
+ set(CMAKE_C_FLAGS_RELEASE "-O3 -funroll-loops -fomit-frame-pointer")
+ set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g3 -O2")
+ set(CMAKE_C_FLAGS_MINSIZEREL "-Os")
endif()
# What compiler do we have and what are their...uhm... peculiarities
if(CMAKE_C_COMPILER_ID MATCHES "(C|c?)lang")
- set(LTM_C_FLAGS ${LTM_C_FLAGS} -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header)
+ list(APPEND LTM_C_FLAGS -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header)
# Clang requires at least '-O1' for dead code eliminiation
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O1")
+ set(CMAKE_C_FLAGS_DEBUG "-O1 ${CMAKE_C_FLAGS_DEBUG}")
endif()
if(CMAKE_C_COMPILER MATCHES "mingw")
- set(LTM_C_FLAGS ${LTM_C_FLAGS} -Wno-shadow)
+ list(APPEND LTM_C_FLAGS -Wno-shadow -Wno-expansion-to-defined -Wno-declaration-after-statement -Wno-bad-function-cast)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
- set(LTM_C_FLAGS ${LTM_C_FLAGS} -Wno-nullability-completeness)
+ list(APPEND LTM_C_FLAGS -Wno-nullability-completeness)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
- set(LTM_C_FLAGS ${LTM_C_FLAGS} -no-undefined)
+ list(APPEND LTM_C_FLAGS -no-undefined)
endif()
# TODO: coverage (lgcov)
@@ -75,14 +78,15 @@ endif()
# in order to allow overriding our defaults.
# ${LTM_CFLAGS} means the user passed it via sth like:
# $ cmake -DLTM_CFLAGS="foo"
-set(LTM_C_FLAGS ${LTM_C_FLAGS} ${LTM_CFLAGS})
-set(LTM_LD_FLAGS ${LTM_LD_FLAGS} ${LTM_LDFLAGS})
+list(APPEND LTM_C_FLAGS ${LTM_CFLAGS})
+list(APPEND LTM_LD_FLAGS ${LTM_LDFLAGS})
#-----------------------------------------------------------------------------
# library target
#-----------------------------------------------------------------------------
add_library(${PROJECT_NAME}
${SOURCES}
+ ${HEADERS}
)
target_include_directories(${PROJECT_NAME} PUBLIC
@@ -100,13 +104,27 @@ target_link_options(${PROJECT_NAME} BEFORE PRIVATE
set_target_properties(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
+ PUBLIC_HEADER tommath.h
)
+option(COMPILE_LTO "Build with LTO enabled")
+if(COMPILE_LTO)
+ check_ipo_supported(RESULT COMPILER_SUPPORTS_LTO)
+ if(COMPILER_SUPPORTS_LTO)
+ set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
+ else()
+ message(SEND_ERROR "This compiler does not support LTO. Reconfigure ${PROJECT_NAME} with -DCOMPILE_LTO=OFF.")
+ endif()
+endif()
#-----------------------------------------------------------------------------
# demo target
#-----------------------------------------------------------------------------
-add_subdirectory(demo)
+
+if(BUILD_TESTING)
+ enable_testing()
+ add_subdirectory(demo)
+endif()
#-----------------------------------------------------------------------------
# Install/export targets and files
@@ -120,14 +138,15 @@ install(TARGETS ${PROJECT_NAME}
EXPORT ${TARGETS_EXPORT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
-
-install(FILES ${HEADERS}
- DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
)
# Install libtommath.pc for pkg-config if we build a shared library
if(BUILD_SHARED_LIBS)
+ # Let the user override the default directory of the pkg-config file (usually this shouldn't be required to be changed)
+ set(CMAKE_INSTALL_PKGCONFIGDIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig" CACHE PATH "Folder where to install .pc files")
+
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/lib${PROJECT_NAME}.pc.in
${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.pc
@@ -135,7 +154,7 @@ if(BUILD_SHARED_LIBS)
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.pc
- DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig
+ DESTINATION ${CMAKE_INSTALL_PKGCONFIGDIR}
)
endif()
@@ -171,8 +190,16 @@ export(PACKAGE ${PROJECT_NAME})
# determine distribution and architecture
find_program(LSB_RELEASE lsb_release)
+find_program(SYSCTL sysctl)
+find_program(UNAME uname)
-execute_process(COMMAND uname -m OUTPUT_VARIABLE MACHINE_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
+if(UNAME)
+ execute_process(COMMAND uname -m OUTPUT_VARIABLE MACHINE_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
+elseif(SYSCTL)
+ execute_process(COMMAND sysctl -b hw.machine_arch OUTPUT_VARIABLE MACHINE_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
+else()
+ string(TOLOWER ${CMAKE_SYSTEM_NAME} MACHINE_ARCH)
+endif()
if(LSB_RELEASE)
execute_process(COMMAND lsb_release -si OUTPUT_VARIABLE LINUX_DISTRO OUTPUT_STRIP_TRAILING_WHITESPACE)