1
- cmake_minimum_required (VERSION 3.1 ...3.18 )
1
+ cmake_minimum_required (VERSION 3.8 ...3.26 )
2
2
3
3
# Fallback for using newer policies on CMake <3.12.
4
4
if (${CMAKE_VERSION} VERSION_LESS 3.12 )
@@ -24,15 +24,86 @@ function(join result_var)
24
24
set (${result_var} "${result} " PARENT_SCOPE )
25
25
endfunction ()
26
26
27
+ # DEPRECATED! Should be merged into add_module_library.
27
28
function (enable_module target )
28
29
if (MSVC )
29
30
set (BMI ${CMAKE_CURRENT_BINARY_DIR} /${target}.ifc )
30
31
target_compile_options (${target}
31
32
PRIVATE /interface /ifcOutput ${BMI}
32
33
INTERFACE /reference fmt=${BMI} )
34
+ set_target_properties (${target} PROPERTIES ADDITIONAL_CLEAN_FILES ${BMI} )
35
+ set_source_files_properties (${BMI} PROPERTIES GENERATED ON )
33
36
endif ()
34
- set_target_properties (${target} PROPERTIES ADDITIONAL_CLEAN_FILES ${BMI} )
35
- set_source_files_properties (${BMI} PROPERTIES GENERATED ON )
37
+ endfunction ()
38
+
39
+ # Adds a library compiled with C++20 module support.
40
+ # `enabled` is a CMake variables that specifies if modules are enabled.
41
+ # If modules are disabled `add_module_library` falls back to creating a
42
+ # non-modular library.
43
+ #
44
+ # Usage:
45
+ # add_module_library(<name> [sources...] FALLBACK [sources...] [IF enabled])
46
+ function (add_module_library name )
47
+ cmake_parse_arguments (AML "" "IF" "FALLBACK" ${ARGN} )
48
+ set (sources ${AML_UNPARSED_ARGUMENTS} )
49
+
50
+ add_library (${name} )
51
+ set_target_properties (${name} PROPERTIES LINKER_LANGUAGE CXX )
52
+
53
+ if (NOT ${${AML_IF}} )
54
+ # Create a non-modular library.
55
+ target_sources (${name} PRIVATE ${AML_FALLBACK} )
56
+ return ()
57
+ endif ()
58
+
59
+ # Modules require C++20.
60
+ target_compile_features (${name} PUBLIC cxx_std_20 )
61
+ if (CMAKE_COMPILER_IS_GNUCXX )
62
+ target_compile_options (${name} PUBLIC -fmodules-ts )
63
+ endif ()
64
+
65
+ # `std` is affected by CMake options and may be higher than C++20.
66
+ get_target_property (std ${name} CXX_STANDARD )
67
+
68
+ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
69
+ set (pcms )
70
+ foreach (src ${sources} )
71
+ get_filename_component (pcm ${src} NAME_WE )
72
+ set (pcm ${pcm} .pcm )
73
+
74
+ # Propagate -fmodule-file=*.pcm to targets that link with this library.
75
+ target_compile_options (
76
+ ${name} PUBLIC -fmodule-file=${CMAKE_CURRENT_BINARY_DIR}/${pcm} )
77
+
78
+ # Use an absolute path to prevent target_link_libraries prepending -l
79
+ # to it.
80
+ set (pcms ${pcms} ${CMAKE_CURRENT_BINARY_DIR} /${pcm} )
81
+ add_custom_command (
82
+ OUTPUT ${pcm}
83
+ COMMAND ${CMAKE_CXX_COMPILER}
84
+ -std=c++${std} -x c++-module --precompile -c
85
+ -o ${pcm} ${CMAKE_CURRENT_SOURCE_DIR} /${src}
86
+ "-I$<JOIN:$<TARGET_PROPERTY:${name} ,INCLUDE_DIRECTORIES>,;-I>"
87
+ # Required by the -I generator expression above.
88
+ COMMAND_EXPAND_LISTS
89
+ DEPENDS ${src} )
90
+ endforeach ()
91
+
92
+ # Add .pcm files as sources to make sure they are built before the library.
93
+ set (sources )
94
+ foreach (pcm ${pcms} )
95
+ get_filename_component (pcm_we ${pcm} NAME_WE )
96
+ set (obj ${pcm_we} .o )
97
+ # Use an absolute path to prevent target_link_libraries prepending -l.
98
+ set (sources ${sources} ${pcm} ${CMAKE_CURRENT_BINARY_DIR} /${obj} )
99
+ add_custom_command (
100
+ OUTPUT ${obj}
101
+ COMMAND ${CMAKE_CXX_COMPILER} $< TARGET_PROPERTY:${name} ,COMPILE_OPTIONS>
102
+ -c -o ${obj} ${pcm}
103
+ DEPENDS ${pcm} )
104
+ endforeach ()
105
+ endif ()
106
+ target_sources (${name} PRIVATE ${sources} )
36
107
endfunction ()
37
108
38
109
include (CMakeParseArguments )
@@ -75,24 +146,14 @@ option(FMT_WERROR "Halt the compilation with an error on compiler warnings."
75
146
76
147
# Options that control generation of various targets.
77
148
option (FMT_DOC "Generate the doc target." ${FMT_MASTER_PROJECT} )
78
- option (FMT_INSTALL "Generate the install target." ${FMT_MASTER_PROJECT} )
149
+ option (FMT_INSTALL "Generate the install target." ON )
79
150
option (FMT_TEST "Generate the test target." ${FMT_MASTER_PROJECT} )
80
151
option (FMT_FUZZ "Generate the fuzz target." OFF )
81
152
option (FMT_CUDA_TEST "Generate the cuda-test target." OFF )
82
153
option (FMT_OS "Include core requiring OS (Windows/Posix) " ON )
83
154
option (FMT_MODULE "Build a module instead of a traditional library." OFF )
84
155
option (FMT_SYSTEM_HEADERS "Expose headers with marking them as system." OFF )
85
156
86
- set (FMT_CAN_MODULE OFF )
87
- if (CMAKE_CXX_STANDARD GREATER 17 AND
88
- # msvc 16.10-pre4
89
- MSVC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.29.30035 )
90
- set (FMT_CAN_MODULE OFF )
91
- endif ()
92
- if (NOT FMT_CAN_MODULE )
93
- set (FMT_MODULE OFF )
94
- message (STATUS "Module support is disabled." )
95
- endif ()
96
157
if (FMT_TEST AND FMT_MODULE )
97
158
# The tests require {fmt} to be compiled as traditional library
98
159
message (STATUS "Testing is incompatible with build mode 'module'." )
@@ -101,6 +162,10 @@ set(FMT_SYSTEM_HEADERS_ATTRIBUTE "")
101
162
if (FMT_SYSTEM_HEADERS )
102
163
set (FMT_SYSTEM_HEADERS_ATTRIBUTE SYSTEM )
103
164
endif ()
165
+ if (CMAKE_SYSTEM_NAME STREQUAL "MSDOS" )
166
+ set (FMT_TEST OFF )
167
+ message (STATUS "MSDOS is incompatible with gtest" )
168
+ endif ()
104
169
105
170
# Get version from core.h
106
171
file (READ include /fmt/core.h core_h )
@@ -118,23 +183,15 @@ message(STATUS "Version: ${FMT_VERSION}")
118
183
message (STATUS "Build type: ${CMAKE_BUILD_TYPE} " )
119
184
120
185
if (NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY )
121
- set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR } /bin )
186
+ set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR } /bin )
122
187
endif ()
123
188
124
189
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
125
190
"${CMAKE_CURRENT_SOURCE_DIR} /support/cmake" )
126
191
127
- include (cxx14 )
192
+ include (CheckCXXCompilerFlag )
128
193
include (JoinPaths )
129
194
130
- list (FIND CMAKE_CXX_COMPILE_FEATURES "cxx_variadic_templates" index )
131
- if (${index} GREATER -1 )
132
- # Use cxx_variadic_templates instead of more appropriate cxx_std_11 for
133
- # compatibility with older CMake versions.
134
- set (FMT_REQUIRED_FEATURES cxx_variadic_templates )
135
- endif ()
136
- message (STATUS "Required features: ${FMT_REQUIRED_FEATURES} " )
137
-
138
195
if (FMT_MASTER_PROJECT AND NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET )
139
196
set_verbose (CMAKE_CXX_VISIBILITY_PRESET hidden CACHE STRING
140
197
"Preset for the export of private symbols" )
@@ -220,28 +277,31 @@ endfunction()
220
277
add_headers (FMT_HEADERS args.h chrono.h color.h compile.h core.h format.h
221
278
format-inl.h os.h ostream.h printf.h ranges.h std.h
222
279
xchar.h )
223
- if (FMT_MODULE )
224
- set (FMT_SOURCES src/fmt.cc )
225
- elseif (FMT_OS )
226
- set (FMT_SOURCES src/format.cc src/os.cc )
227
- else ()
228
- set (FMT_SOURCES src/format.cc )
280
+ set (FMT_SOURCES src/format.cc )
281
+ if (FMT_OS )
282
+ set (FMT_SOURCES ${FMT_SOURCES} src/os.cc )
229
283
endif ()
230
284
231
- add_library (fmt ${FMT_SOURCES} ${FMT_HEADERS} README.rst ChangeLog.rst )
285
+ add_module_library (fmt src/fmt.cc FALLBACK
286
+ ${FMT_SOURCES} ${FMT_HEADERS} README.rst ChangeLog.rst
287
+ IF FMT_MODULE )
232
288
add_library (fmt::fmt ALIAS fmt )
289
+ if (FMT_MODULE )
290
+ enable_module (fmt )
291
+ endif ()
233
292
234
293
if (FMT_WERROR )
235
294
target_compile_options (fmt PRIVATE ${WERROR_FLAG} )
236
295
endif ()
237
296
if (FMT_PEDANTIC )
238
297
target_compile_options (fmt PRIVATE ${PEDANTIC_COMPILE_FLAGS} )
239
298
endif ()
240
- if (FMT_MODULE )
241
- enable_module (fmt )
242
- endif ()
243
299
244
- target_compile_features (fmt INTERFACE ${FMT_REQUIRED_FEATURES} )
300
+ if (cxx_std_11 IN_LIST CMAKE_CXX_COMPILE_FEATURES )
301
+ target_compile_features (fmt PUBLIC cxx_std_11 )
302
+ else ()
303
+ message (WARNING "Feature cxx_std_11 is unknown for the CXX compiler" )
304
+ endif ()
245
305
246
306
target_include_directories (fmt ${FMT_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
247
307
$< BUILD_INTERFACE:${PROJECT_SOURCE_DIR} /include>
@@ -262,13 +322,7 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug")
262
322
endif ()
263
323
264
324
if (BUILD_SHARED_LIBS )
265
- if (UNIX AND NOT APPLE AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "SunOS" AND
266
- NOT EMSCRIPTEN )
267
- # Fix rpmlint warning:
268
- # unused-direct-shlib-dependency /usr/lib/libformat.so.1.1.0 /lib/libm.so.6.
269
- target_link_libraries (fmt -Wl,--as-needed )
270
- endif ()
271
- target_compile_definitions (fmt PRIVATE FMT_EXPORT INTERFACE FMT_SHARED )
325
+ target_compile_definitions (fmt PRIVATE FMT_LIB_EXPORT INTERFACE FMT_SHARED )
272
326
endif ()
273
327
if (FMT_SAFE_DURATION_CAST )
274
328
target_compile_definitions (fmt PUBLIC FMT_SAFE_DURATION_CAST )
@@ -278,7 +332,7 @@ add_library(fmt-header-only INTERFACE)
278
332
add_library (fmt::fmt-header-only ALIAS fmt-header-only )
279
333
280
334
target_compile_definitions (fmt-header-only INTERFACE FMT_HEADER_ONLY=1 )
281
- target_compile_features (fmt-header-only INTERFACE ${FMT_REQUIRED_FEATURES} )
335
+ target_compile_features (fmt-header-only INTERFACE cxx_std_11 )
282
336
283
337
target_include_directories (fmt-header-only ${FMT_SYSTEM_HEADERS_ATTRIBUTE} INTERFACE
284
338
$< BUILD_INTERFACE:${PROJECT_SOURCE_DIR} /include>
@@ -300,7 +354,7 @@ if (FMT_INSTALL)
300
354
"Installation directory for libraries, a relative path that "
301
355
"will be joined to ${CMAKE_INSTALL_PREFIX} or an absolute path." )
302
356
303
- set_verbose (FMT_PKGCONFIG_DIR ${CMAKE_INSTALL_LIBDIR} /pkgconfig CACHE PATH
357
+ set_verbose (FMT_PKGCONFIG_DIR ${CMAKE_INSTALL_LIBDIR} /pkgconfig CACHE STRING
304
358
"Installation directory for pkgconfig (.pc) files, a relative "
305
359
"path that will be joined with ${CMAKE_INSTALL_PREFIX} or an "
306
360
"absolute path." )
@@ -330,7 +384,6 @@ if (FMT_INSTALL)
330
384
LIBRARY DESTINATION ${FMT_LIB_DIR}
331
385
ARCHIVE DESTINATION ${FMT_LIB_DIR}
332
386
PUBLIC_HEADER DESTINATION "${FMT_INC_DIR} /fmt"
333
- FRAMEWORK DESTINATION "."
334
387
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )
335
388
336
389
# Use a namespace because CMake provides better diagnostics for namespaced
@@ -345,8 +398,6 @@ if (FMT_INSTALL)
345
398
install (EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR}
346
399
NAMESPACE fmt:: )
347
400
348
- install (FILES $< TARGET_PDB_FILE:${INSTALL_TARGETS} >
349
- DESTINATION ${FMT_LIB_DIR} OPTIONAL )
350
401
install (FILES "${pkgconfig} " DESTINATION "${FMT_PKGCONFIG_DIR} " )
351
402
endif ()
352
403
0 commit comments