]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | cmake_minimum_required(VERSION 3.1.0) |
2 | ||
3 | # Use newer policies if available, up to most recent tested version of CMake. | |
4 | if(${CMAKE_VERSION} VERSION_LESS 3.11) | |
5 | cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) | |
6 | else() | |
7 | cmake_policy(VERSION 3.11) | |
8 | endif() | |
9 | ||
10 | # Determine if fmt is built as a subproject (using add_subdirectory) | |
11 | # or if it is the master project. | |
12 | set(MASTER_PROJECT OFF) | |
13 | if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) | |
14 | set(MASTER_PROJECT ON) | |
15 | message(STATUS "CMake version: ${CMAKE_VERSION}") | |
16 | endif () | |
17 | ||
18 | # Joins arguments and places the results in ${result_var}. | |
19 | function(join result_var) | |
20 | set(result ) | |
21 | foreach (arg ${ARGN}) | |
22 | set(result "${result}${arg}") | |
23 | endforeach () | |
24 | set(${result_var} "${result}" PARENT_SCOPE) | |
25 | endfunction() | |
26 | ||
27 | # Set the default CMAKE_BUILD_TYPE to Release. | |
28 | # This should be done before the project command since the latter can set | |
29 | # CMAKE_BUILD_TYPE itself (it does so for nmake). | |
30 | if (NOT CMAKE_BUILD_TYPE) | |
31 | join(doc "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or " | |
32 | "CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.") | |
33 | set(CMAKE_BUILD_TYPE Release CACHE STRING ${doc}) | |
34 | endif () | |
35 | ||
36 | option(FMT_PEDANTIC "Enable extra warnings and expensive tests." OFF) | |
37 | option(FMT_WERROR "Halt the compilation with an error on compiler warnings." OFF) | |
38 | ||
39 | # Options that control generation of various targets. | |
40 | option(FMT_DOC "Generate the doc target." ${MASTER_PROJECT}) | |
41 | option(FMT_INSTALL "Generate the install target." ${MASTER_PROJECT}) | |
42 | option(FMT_TEST "Generate the test target." ${MASTER_PROJECT}) | |
43 | ||
44 | project(FMT) | |
45 | ||
46 | # Get version from core.h | |
47 | file(READ include/fmt/core.h core_h) | |
48 | if (NOT core_h MATCHES "FMT_VERSION ([0-9]+)([0-9][0-9])([0-9][0-9])") | |
49 | message(FATAL_ERROR "Cannot get FMT_VERSION from core.h.") | |
50 | endif () | |
51 | # Use math to skip leading zeros if any. | |
52 | math(EXPR CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1}) | |
53 | math(EXPR CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2}) | |
54 | math(EXPR CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3}) | |
55 | join(FMT_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}. | |
56 | ${CPACK_PACKAGE_VERSION_PATCH}) | |
57 | message(STATUS "Version: ${FMT_VERSION}") | |
58 | ||
59 | message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") | |
60 | ||
61 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) | |
62 | ||
63 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} | |
64 | "${CMAKE_CURRENT_SOURCE_DIR}/support/cmake") | |
65 | ||
66 | include(cxx14) | |
67 | include(CheckCXXCompilerFlag) | |
68 | ||
69 | if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") | |
70 | set(PEDANTIC_COMPILE_FLAGS -pedantic-errors -Wall -Wextra -pedantic | |
eafe8130 TL |
71 | -Wold-style-cast -Wundef |
72 | -Wredundant-decls -Wwrite-strings -Wpointer-arith | |
11fdf7f2 TL |
73 | -Wcast-qual -Wformat=2 -Wmissing-include-dirs |
74 | -Wcast-align -Wnon-virtual-dtor | |
75 | -Wctor-dtor-privacy -Wdisabled-optimization | |
76 | -Winvalid-pch -Woverloaded-virtual | |
eafe8130 | 77 | -Wno-ctor-dtor-privacy -Wno-dangling-else |
11fdf7f2 TL |
78 | -Wno-format-nonliteral -Wno-sign-conversion -Wno-shadow) |
79 | if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) | |
80 | set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept) | |
81 | endif () | |
82 | if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) | |
83 | set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wdouble-promotion | |
84 | -Wtrampolines -Wzero-as-null-pointer-constant -Wuseless-cast | |
85 | -Wvector-operation-performance -Wsized-deallocation) | |
86 | endif () | |
87 | if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) | |
88 | set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wshift-overflow=2 | |
89 | -Wnull-dereference -Wduplicated-cond) | |
90 | endif () | |
11fdf7f2 TL |
91 | set(WERROR_FLAG -Werror) |
92 | endif () | |
93 | ||
94 | if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") | |
eafe8130 TL |
95 | set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -pedantic) |
96 | check_cxx_compiler_flag(-Wzero-as-null-pointer-constant HAS_NULLPTR_WARNING) | |
11fdf7f2 TL |
97 | if (HAS_NULLPTR_WARNING) |
98 | set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} | |
eafe8130 | 99 | -Wzero-as-null-pointer-constant) |
11fdf7f2 | 100 | endif () |
eafe8130 | 101 | set(WERROR_FLAG -Werror) |
11fdf7f2 TL |
102 | endif () |
103 | ||
104 | if (MSVC) | |
105 | set(PEDANTIC_COMPILE_FLAGS /W3) | |
106 | set(WERROR_FLAG /WX) | |
107 | endif () | |
108 | ||
109 | if (MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio") | |
110 | # If Microsoft SDK is installed create script run-msbuild.bat that | |
111 | # calls SetEnv.cmd to set up build environment and runs msbuild. | |
112 | # It is useful when building Visual Studio projects with the SDK | |
113 | # toolchain rather than Visual Studio. | |
114 | include(FindSetEnv) | |
115 | if (WINSDK_SETENV) | |
116 | set(MSBUILD_SETUP "call \"${WINSDK_SETENV}\"") | |
117 | endif () | |
118 | # Set FrameworkPathOverride to get rid of MSB3644 warnings. | |
119 | set(netfxpath "C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.0") | |
120 | file(WRITE run-msbuild.bat " | |
121 | ${MSBUILD_SETUP} | |
122 | ${CMAKE_MAKE_PROGRAM} -p:FrameworkPathOverride=\"${netfxpath}\" %*") | |
123 | endif () | |
124 | ||
125 | include(CheckSymbolExists) | |
126 | if (WIN32) | |
127 | check_symbol_exists(open io.h HAVE_OPEN) | |
128 | else () | |
129 | check_symbol_exists(open fcntl.h HAVE_OPEN) | |
130 | endif () | |
131 | ||
132 | function(add_headers VAR) | |
133 | set(headers ${${VAR}}) | |
134 | foreach (header ${ARGN}) | |
135 | set(headers ${headers} include/fmt/${header}) | |
136 | endforeach() | |
137 | set(${VAR} ${headers} PARENT_SCOPE) | |
138 | endfunction() | |
139 | ||
140 | # Define the fmt library, its includes and the needed defines. | |
eafe8130 TL |
141 | add_headers(FMT_HEADERS chrono.h color.h core.h format.h format-inl.h locale.h |
142 | ostream.h printf.h time.h ranges.h) | |
11fdf7f2 TL |
143 | set(FMT_SOURCES src/format.cc) |
144 | if (HAVE_OPEN) | |
145 | add_headers(FMT_HEADERS posix.h) | |
146 | set(FMT_SOURCES ${FMT_SOURCES} src/posix.cc) | |
147 | endif () | |
148 | ||
149 | add_library(fmt ${FMT_SOURCES} ${FMT_HEADERS} README.rst ChangeLog.rst) | |
150 | add_library(fmt::fmt ALIAS fmt) | |
151 | ||
152 | if (FMT_WERROR) | |
153 | target_compile_options(fmt PRIVATE ${WERROR_FLAG}) | |
154 | endif () | |
155 | if (FMT_PEDANTIC) | |
156 | target_compile_options(fmt PRIVATE ${PEDANTIC_COMPILE_FLAGS}) | |
157 | endif () | |
158 | ||
159 | target_include_directories(fmt PUBLIC | |
160 | $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> | |
161 | $<INSTALL_INTERFACE:include>) | |
162 | ||
163 | set_target_properties(fmt PROPERTIES | |
164 | VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR} | |
165 | DEBUG_POSTFIX d) | |
166 | ||
167 | if (BUILD_SHARED_LIBS) | |
168 | if (UNIX AND NOT APPLE) | |
169 | # Fix rpmlint warning: | |
170 | # unused-direct-shlib-dependency /usr/lib/libformat.so.1.1.0 /lib/libm.so.6. | |
171 | target_link_libraries(fmt -Wl,--as-needed) | |
172 | endif () | |
173 | target_compile_definitions(fmt PRIVATE FMT_EXPORT INTERFACE FMT_SHARED) | |
174 | endif () | |
175 | ||
176 | add_library(fmt-header-only INTERFACE) | |
177 | add_library(fmt::fmt-header-only ALIAS fmt-header-only) | |
178 | ||
179 | target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1) | |
180 | ||
181 | target_include_directories(fmt-header-only INTERFACE | |
182 | $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> | |
183 | $<INSTALL_INTERFACE:include>) | |
184 | ||
185 | # Install targets. | |
186 | if (FMT_INSTALL) | |
187 | include(GNUInstallDirs) | |
188 | include(CMakePackageConfigHelpers) | |
189 | set(FMT_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/fmt CACHE STRING | |
190 | "Installation directory for cmake files, relative to ${CMAKE_INSTALL_PREFIX}.") | |
191 | set(version_config ${PROJECT_BINARY_DIR}/fmt-config-version.cmake) | |
192 | set(project_config ${PROJECT_BINARY_DIR}/fmt-config.cmake) | |
eafe8130 | 193 | set(pkgconfig ${PROJECT_BINARY_DIR}/fmt.pc) |
11fdf7f2 TL |
194 | set(targets_export_name fmt-targets) |
195 | ||
196 | set (INSTALL_TARGETS fmt) | |
197 | if (TARGET fmt-header-only) | |
198 | set(INSTALL_TARGETS ${INSTALL_TARGETS} fmt-header-only) | |
199 | endif () | |
200 | ||
201 | set(FMT_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING | |
202 | "Installation directory for libraries, relative to ${CMAKE_INSTALL_PREFIX}.") | |
203 | ||
204 | set(FMT_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR}/fmt CACHE STRING | |
205 | "Installation directory for include files, relative to ${CMAKE_INSTALL_PREFIX}.") | |
206 | ||
eafe8130 TL |
207 | set(FMT_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH |
208 | "Installation directory for pkgconfig (.pc) files, relative to ${CMAKE_INSTALL_PREFIX}.") | |
209 | ||
11fdf7f2 TL |
210 | # Generate the version, config and target files into the build directory. |
211 | write_basic_package_version_file( | |
212 | ${version_config} | |
213 | VERSION ${FMT_VERSION} | |
214 | COMPATIBILITY AnyNewerVersion) | |
eafe8130 TL |
215 | configure_file( |
216 | "${PROJECT_SOURCE_DIR}/support/cmake/fmt.pc.in" | |
217 | "${pkgconfig}" | |
218 | @ONLY) | |
11fdf7f2 TL |
219 | configure_package_config_file( |
220 | ${PROJECT_SOURCE_DIR}/support/cmake/fmt-config.cmake.in | |
221 | ${project_config} | |
222 | INSTALL_DESTINATION ${FMT_CMAKE_DIR}) | |
223 | # Use a namespace because CMake provides better diagnostics for namespaced | |
224 | # imported targets. | |
225 | export(TARGETS ${INSTALL_TARGETS} NAMESPACE fmt:: | |
226 | FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake) | |
227 | ||
228 | # Install version, config and target files. | |
229 | install( | |
230 | FILES ${project_config} ${version_config} | |
231 | DESTINATION ${FMT_CMAKE_DIR}) | |
232 | install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR} | |
233 | NAMESPACE fmt::) | |
234 | ||
235 | # Install the library and headers. | |
236 | install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name} | |
237 | DESTINATION ${FMT_LIB_DIR}) | |
eafe8130 TL |
238 | |
239 | install(FILES $<TARGET_PDB_FILE:${INSTALL_TARGETS}> DESTINATION ${FMT_LIB_DIR} OPTIONAL) | |
11fdf7f2 | 240 | install(FILES ${FMT_HEADERS} DESTINATION ${FMT_INC_DIR}) |
eafe8130 | 241 | install(FILES "${pkgconfig}" DESTINATION "${FMT_PKGCONFIG_DIR}") |
11fdf7f2 TL |
242 | endif () |
243 | ||
244 | if (FMT_DOC) | |
245 | add_subdirectory(doc) | |
246 | endif () | |
247 | ||
248 | if (FMT_TEST) | |
249 | enable_testing() | |
250 | add_subdirectory(test) | |
251 | endif () | |
252 | ||
253 | set(gitignore ${PROJECT_SOURCE_DIR}/.gitignore) | |
254 | if (MASTER_PROJECT AND EXISTS ${gitignore}) | |
255 | # Get the list of ignored files from .gitignore. | |
256 | file (STRINGS ${gitignore} lines) | |
257 | LIST(REMOVE_ITEM lines /doc/html) | |
258 | foreach (line ${lines}) | |
259 | string(REPLACE "." "[.]" line "${line}") | |
260 | string(REPLACE "*" ".*" line "${line}") | |
261 | set(ignored_files ${ignored_files} "${line}$" "${line}/") | |
262 | endforeach () | |
263 | set(ignored_files ${ignored_files} | |
264 | /.git /breathe /format-benchmark sphinx/ .buildinfo .doctrees) | |
265 | ||
266 | set(CPACK_SOURCE_GENERATOR ZIP) | |
267 | set(CPACK_SOURCE_IGNORE_FILES ${ignored_files}) | |
268 | set(CPACK_SOURCE_PACKAGE_FILE_NAME fmt-${FMT_VERSION}) | |
269 | set(CPACK_PACKAGE_NAME fmt) | |
270 | set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.rst) | |
271 | include(CPack) | |
272 | endif () |