@@ -10,8 +10,7 @@ endif ()
1010# or if it is the master project.
1111if (NOT DEFINED FMT_MASTER_PROJECT)
1212 set (FMT_MASTER_PROJECT OFF )
13- # NOTE: source vs current_source detection is unreliable
14- # this heuristic is more generally applicable esp w.r.t FetchContent
13+ # Checking project name is more reliable than checking source directories.
1514 if (NOT DEFINED PROJECT_NAME )
1615 set (FMT_MASTER_PROJECT ON )
1716 message (STATUS "CMake version: ${CMAKE_VERSION} " )
@@ -27,98 +26,6 @@ function(join result_var)
2726 set (${result_var} "${result} " PARENT_SCOPE )
2827endfunction ()
2928
30- # DEPRECATED! Should be merged into add_module_library.
31- function (enable_module target )
32- if (MSVC )
33- if (NOT CMAKE_GENERATOR STREQUAL "Ninja" )
34- set (BMI_DIR "${CMAKE_CURRENT_BINARY_DIR} " )
35- file (TO_NATIVE_PATH "${BMI_DIR} /${target} .ifc" BMI )
36- target_compile_options (${target}
37- PRIVATE /interface /ifcOutput ${BMI}
38- INTERFACE /reference fmt=${BMI} )
39- set_target_properties (${target} PROPERTIES ADDITIONAL_CLEAN_FILES ${BMI} )
40- set_source_files_properties (${BMI} PROPERTIES GENERATED ON )
41- endif ()
42- endif ()
43- endfunction ()
44-
45- # Adds a library compiled with C++20 module support.
46- # `enabled` is a CMake variables that specifies if modules are enabled.
47- # If modules are disabled `add_module_library` falls back to creating a
48- # non-modular library.
49- #
50- # Usage:
51- # add_module_library(<name> [sources...] FALLBACK [sources...] [IF_MODULE enabled]
52- # [USE_CMAKE_MODULES true])
53- function (add_module_library name )
54- cmake_parse_arguments (AML "" "IF_MODULE;USE_CMAKE_MODULES" "FALLBACK" ${ARGN} )
55- set (sources ${AML_UNPARSED_ARGUMENTS} )
56-
57- add_library (${name} )
58- set_target_properties (${name} PROPERTIES LINKER_LANGUAGE CXX )
59-
60- if (NOT ${AML_IF_MODULE} )
61- # Create a non-modular library.
62- target_sources (${name} PRIVATE ${AML_FALLBACK} )
63- set_target_properties (${name} PROPERTIES CXX_SCAN_FOR_MODULES OFF )
64- return ()
65- endif ()
66-
67- # Modules require C++20.
68- target_compile_features (${name} PUBLIC cxx_std_20 )
69-
70- if (${AML_USE_CMAKE_MODULES} )
71- target_sources (${name} PUBLIC FILE_SET fmt_module TYPE CXX_MODULES
72- FILES ${sources} )
73- else ()
74- if (CMAKE_COMPILER_IS_GNUCXX)
75- target_compile_options (${name} PUBLIC -fmodules-ts )
76- endif ()
77- # `std` is affected by CMake options and may be higher than C++20.
78- get_target_property (std ${name} CXX_STANDARD )
79-
80- if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
81- set (pcms)
82- foreach (src ${sources} )
83- get_filename_component (pcm ${src} NAME_WE )
84- set (pcm ${pcm} .pcm)
85-
86- # Propagate -fmodule-file=*.pcm to targets that link with this library.
87- target_compile_options (
88- ${name} PUBLIC -fmodule-file=${CMAKE_CURRENT_BINARY_DIR}/${pcm} )
89-
90- # Use an absolute path to prevent target_link_libraries prepending -l
91- # to it.
92- set (pcms ${pcms} ${CMAKE_CURRENT_BINARY_DIR} /${pcm} )
93- add_custom_command (
94- OUTPUT ${pcm}
95- COMMAND ${CMAKE_CXX_COMPILER}
96- -std=c++${std} -x c++-module --precompile -c
97- -o ${pcm} ${CMAKE_CURRENT_SOURCE_DIR} /${src}
98- "-I$<JOIN :$<TARGET_PROPERTY :${name} ,INCLUDE_DIRECTORIES >,;-I >"
99- # Required by the -I generator expression above.
100- COMMAND_EXPAND_LISTS
101- DEPENDS ${src} )
102- endforeach ()
103-
104- # Add .pcm files as sources to make sure they are built before the library.
105- set (sources)
106- foreach (pcm ${pcms} )
107- get_filename_component (pcm_we ${pcm} NAME_WE )
108- set (obj ${pcm_we} .o)
109- # Use an absolute path to prevent target_link_libraries prepending -l.
110- set (sources ${sources} ${pcm} ${CMAKE_CURRENT_BINARY_DIR} /${obj} )
111- add_custom_command (
112- OUTPUT ${obj}
113- COMMAND ${CMAKE_CXX_COMPILER} $<TARGET_PROPERTY :${name} ,COMPILE_OPTIONS >
114- -c -o ${obj} ${pcm}
115- DEPENDS ${pcm} )
116- endforeach ()
117- endif ()
118- target_sources (${name} PRIVATE ${sources} )
119- endif ()
120- endfunction ()
121-
12229include (CMakeParseArguments )
12330
12431# Sets a cache variable with a docstring joined from multiple arguments:
@@ -149,26 +56,20 @@ endif ()
14956
15057project (FMT CXX )
15158
152- # Determine Support for the C++ Module Scanning Features
153- # Requires C++20, CMake>=3.28 and (Ninja >= 1.11 OR Visual Studio >=17.4)
154- # The project() CMake Function sets several variables including those
155- # needed for Compiler Versions
59+ # Determine support for the C++ module scanning.
60+ # Requires C++20, CMake >= 3.28 and (Ninja >= 1.11 OR Visual Studio >= 17.4).
15661set (FMT_USE_CMAKE_MODULES FALSE )
157- if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.28
158- AND CMAKE_CXX_STANDARD GREATER_EQUAL 20)
159- # Check Version of Ninja to determine CXX_MODULES support
62+ if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.28 AND
63+ CMAKE_CXX_STANDARD GREATER_EQUAL 20)
16064 if (CMAKE_GENERATOR STREQUAL "Ninja" )
16165 execute_process (COMMAND "${CMAKE_MAKE_PROGRAM} " "--version"
16266 OUTPUT_VARIABLE NINJA_VERSION )
163- message (STATUS "Ninja Version: ${NINJA_VERSION} " )
16467 if (NINJA_VERSION VERSION_GREATER_EQUAL 1.11)
16568 set (FMT_USE_CMAKE_MODULES TRUE )
166- message (STATUS "Using CXX Modules by Default with Ninja" )
16769 endif ()
168- elseif (CMAKE_GENERATOR MATCHES "^Visual Studio"
169- AND MSVC_VERSION GREATER_EQUAL 1934)
70+ elseif (CMAKE_GENERATOR MATCHES "^Visual Studio" AND
71+ MSVC_VERSION GREATER_EQUAL 1934)
17072 set (FMT_USE_CMAKE_MODULES TRUE )
171- message (STATUS "Using CXX Modules by Default with Visual Studio" )
17273 endif ()
17374endif ()
17475
@@ -188,18 +89,14 @@ option(FMT_TEST "Generate the test target." ${FMT_MASTER_PROJECT})
18889option (FMT_FUZZ "Generate the fuzz target." OFF )
18990option (FMT_CUDA_TEST "Generate the cuda-test target." OFF )
19091option (FMT_OS "Include OS-specific APIs." ON )
191- option (FMT_MODULE "Build a module library in addition to the traditional library ." ${FMT_USE_CMAKE_MODULES} )
92+ option (FMT_MODULE "Build a module library." ${FMT_USE_CMAKE_MODULES} )
19293option (FMT_SYSTEM_HEADERS "Expose headers with marking them as system." OFF )
19394option (FMT_UNICODE "Enable Unicode support." ON )
19495
19596set (FMT_SYSTEM_HEADERS_ATTRIBUTE "" )
19697if (FMT_SYSTEM_HEADERS)
19798 set (FMT_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
19899endif ()
199- if (CMAKE_SYSTEM_NAME STREQUAL "MSDOS" )
200- set (FMT_TEST OFF )
201- message (STATUS "MSDOS is incompatible with gtest" )
202- endif ()
203100
204101# Get version from base.h
205102file (READ include /fmt/base.h base_h )
@@ -234,7 +131,8 @@ endif ()
234131
235132if (FMT_MASTER_PROJECT AND NOT DEFINED CMAKE_VISIBILITY_INLINES_HIDDEN)
236133 set_verbose (CMAKE_VISIBILITY_INLINES_HIDDEN ON CACHE BOOL
237- "Whether to add a compile flag to hide symbols of inline functions" )
134+ "Whether to add a compile flag to hide symbols of inline "
135+ "functions" )
238136endif ()
239137
240138if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" )
@@ -304,6 +202,13 @@ if (FMT_MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio")
304202 ${CMAKE_MAKE_PROGRAM} -p:FrameworkPathOverride=\" ${netfxpath} \" %*" )
305203endif ()
306204
205+ function (set_include_directories target kind )
206+ target_include_directories (${target}
207+ ${FMT_SYSTEM_HEADERS_ATTRIBUTE} BEFORE ${kind}
208+ $<BUILD_INTERFACE :${PROJECT_SOURCE_DIR} /include >
209+ $<INSTALL_INTERFACE :${FMT_INC_DIR} >)
210+ endfunction ()
211+
307212function (add_headers VAR )
308213 set (headers ${${VAR} })
309214 foreach (header ${ARGN} )
@@ -312,18 +217,16 @@ function(add_headers VAR)
312217 set (${VAR} ${headers} PARENT_SCOPE )
313218endfunction ()
314219
315- # Define the fmt library, its includes and the needed defines .
220+ # Define the fmt library, its includes and configuration macros .
316221set (FMT_HEADERS)
317222add_headers (FMT_HEADERS args.h base.h chrono.h color.h compile.h core.h format.h
318223 format-inl.h os.h ostream.h printf.h ranges.h std.h
319224 xchar.h )
320225set (FMT_SOURCES src/format.cc)
321226
322- # add regular library by setting IF_MODULE=FALSE
323- add_module_library (fmt src/fmt.cc
324- FALLBACK ${FMT_SOURCES} ${FMT_HEADERS} README.md ChangeLog.md
325- IF_MODULE FALSE )
227+ add_library (fmt ${FMT_SOURCES} ${FMT_HEADERS} README.md ChangeLog.md )
326228add_library (fmt::fmt ALIAS fmt )
229+ set_include_directories (fmt PUBLIC )
327230
328231if (FMT_OS)
329232 target_sources (fmt PRIVATE src/os.cc )
@@ -344,10 +247,6 @@ else ()
344247 message (WARNING "Feature cxx_std_11 is unknown for the CXX compiler" )
345248endif ()
346249
347- target_include_directories (fmt ${FMT_SYSTEM_HEADERS_ATTRIBUTE} BEFORE PUBLIC
348- $<BUILD_INTERFACE :${PROJECT_SOURCE_DIR} /include >
349- $<INSTALL_INTERFACE :${FMT_INC_DIR} >)
350-
351250set (FMT_DEBUG_POSTFIX d CACHE STRING "Debug library postfix." )
352251
353252set_target_properties (fmt PROPERTIES
@@ -377,37 +276,100 @@ if (FMT_SAFE_DURATION_CAST)
377276 target_compile_definitions (fmt PUBLIC FMT_SAFE_DURATION_CAST )
378277endif ()
379278
380- if (FMT_MODULE)
381- add_module_library (fmt-module "src/fmt.cc"
382- IF_MODULE TRUE
383- USE_CMAKE_MODULES ${FMT_USE_CMAKE_MODULES} )
279+ # DEPRECATED! Should be merged into add_module_library.
280+ function (enable_module target )
281+ if (MSVC )
282+ if (NOT CMAKE_GENERATOR STREQUAL "Ninja" )
283+ set (BMI_DIR "${CMAKE_CURRENT_BINARY_DIR} " )
284+ file (TO_NATIVE_PATH "${BMI_DIR} /${target} .ifc" BMI )
285+ target_compile_options (${target}
286+ PRIVATE /interface /ifcOutput ${BMI}
287+ INTERFACE /reference fmt=${BMI} )
288+ set_target_properties (${target} PROPERTIES ADDITIONAL_CLEAN_FILES ${BMI} )
289+ set_source_files_properties (${BMI} PROPERTIES GENERATED ON )
290+ endif ()
291+ endif ()
292+ endfunction ()
384293
385- add_library (fmt::fmt-module ALIAS fmt-module )
386- enable_module (fmt-module )
294+ # Adds a library compiled with C++20 module support.
295+ #
296+ # Usage:
297+ # add_module_library(<name> [sources...] [USE_CMAKE_MODULES TRUE])
298+ function (add_module_library name )
299+ cmake_parse_arguments (AML "" "USE_CMAKE_MODULES" "" ${ARGN} )
300+ set (sources ${AML_UNPARSED_ARGUMENTS} )
387301
388- if (FMT_WERROR)
389- target_compile_options (fmt-module PRIVATE ${WERROR_FLAG} )
302+ add_library (${name} )
303+ set_target_properties (${name} PROPERTIES LINKER_LANGUAGE CXX )
304+
305+ # Modules require C++20.
306+ target_compile_features (${name} PUBLIC cxx_std_20 )
307+
308+ if (${AML_USE_CMAKE_MODULES} )
309+ target_sources (${name} PUBLIC FILE_SET fmt TYPE CXX_MODULES
310+ FILES ${sources} )
311+ return ()
390312 endif ()
391- if (FMT_PEDANTIC)
392- target_compile_options (fmt-module PRIVATE ${PEDANTIC_COMPILE_FLAGS} )
313+
314+ if (CMAKE_COMPILER_IS_GNUCXX)
315+ target_compile_options (${name} PUBLIC -fmodules-ts )
393316 endif ()
394317
395- if (FMT_USE_CMAKE_MODULES)
396- target_sources (fmt-module PRIVATE FILE_SET fmt_module_headers TYPE HEADERS
397- BASE_DIRS ${PROJECT_SOURCE_DIR} /include FILES ${FMT_HEADERS} )
398- else ()
399- target_include_directories (fmt-module ${FMT_SYSTEM_HEADERS_ATTRIBUTE} BEFORE PUBLIC
400- $<BUILD_INTERFACE :${PROJECT_SOURCE_DIR} /include >
401- $<INSTALL_INTERFACE :${FMT_INC_DIR} >)
318+ # `std` is affected by CMake options and may be higher than C++20.
319+ get_target_property (std ${name} CXX_STANDARD )
320+
321+ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
322+ set (pcms)
323+ foreach (src ${sources} )
324+ get_filename_component (pcm ${src} NAME_WE )
325+ set (pcm ${pcm} .pcm)
326+
327+ # Propagate -fmodule-file=*.pcm to targets that link with this library.
328+ target_compile_options (
329+ ${name} PUBLIC -fmodule-file=${CMAKE_CURRENT_BINARY_DIR}/${pcm} )
330+
331+ # Use an absolute path to prevent target_link_libraries prepending -l
332+ # to it.
333+ set (pcms ${pcms} ${CMAKE_CURRENT_BINARY_DIR} /${pcm} )
334+ add_custom_command (
335+ OUTPUT ${pcm}
336+ COMMAND ${CMAKE_CXX_COMPILER}
337+ -std=c++${std} -x c++-module --precompile -c
338+ -o ${pcm} ${CMAKE_CURRENT_SOURCE_DIR} /${src}
339+ "-I$<JOIN :$<TARGET_PROPERTY :${name} ,INCLUDE_DIRECTORIES >,;-I >"
340+ # Required by the -I generator expression above.
341+ COMMAND_EXPAND_LISTS
342+ DEPENDS ${src} )
343+ endforeach ()
344+
345+ # Add .pcm files as sources to make sure they are built before the library.
346+ set (sources)
347+ foreach (pcm ${pcms} )
348+ get_filename_component (pcm_we ${pcm} NAME_WE )
349+ set (obj ${pcm_we} .o)
350+ # Use an absolute path to prevent target_link_libraries prepending -l.
351+ set (sources ${sources} ${pcm} ${CMAKE_CURRENT_BINARY_DIR} /${obj} )
352+ add_custom_command (
353+ OUTPUT ${obj}
354+ COMMAND ${CMAKE_CXX_COMPILER} $<TARGET_PROPERTY :${name} ,COMPILE_OPTIONS >
355+ -c -o ${obj} ${pcm}
356+ DEPENDS ${pcm} )
357+ endforeach ()
402358 endif ()
359+ target_sources (${name} PRIVATE ${sources} )
360+ endfunction ()
403361
404- set (FMT_DEBUG_POSTFIX d CACHE STRING "Debug library postfix." )
362+ if (FMT_MODULE)
363+ add_module_library (fmt-module src/fmt.cc
364+ USE_CMAKE_MODULES ${FMT_USE_CMAKE_MODULES} )
365+ add_library (fmt::fmt-module ALIAS fmt-module )
366+ set_include_directories (fmt-module PUBLIC )
367+ enable_module (fmt-module )
405368
406369 set_target_properties (fmt-module PROPERTIES
407370 VERSION ${FMT_VERSION}
408371 SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR}
409- DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX} "
410- )
372+ DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX} " )
411373endif ()
412374
413375add_library (fmt-header-only INTERFACE )
@@ -428,11 +390,7 @@ endif ()
428390
429391target_compile_definitions (fmt-header-only INTERFACE FMT_HEADER_ONLY=1 )
430392target_compile_features (fmt-header-only INTERFACE cxx_std_11 )
431-
432- target_include_directories (fmt-header-only
433- ${FMT_SYSTEM_HEADERS_ATTRIBUTE} BEFORE INTERFACE
434- $<BUILD_INTERFACE :${PROJECT_SOURCE_DIR} /include >
435- $<INSTALL_INTERFACE :${FMT_INC_DIR} >)
393+ set_include_directories (fmt-header-only INTERFACE )
436394
437395add_library (fmt-c STATIC src/fmt-c.cc )
438396target_compile_features (fmt-c INTERFACE c_std_11 )
@@ -485,15 +443,9 @@ if (FMT_INSTALL)
485443
486444 if (FMT_MODULE)
487445 list (APPEND INSTALL_TARGETS fmt-module)
488- endif ()
489-
490- set (INSTALL_FILE_SET)
491- if (${CMAKE_VERSION} VERSION_GREATER "3.22" )
492- list (APPEND INSTALL_FILE_SET FILE_SET fmt DESTINATION "${FMT_INC_DIR} /fmt" )
493- list (APPEND INSTALL_FILE_SET FILE_SET fmt_header_only DESTINATION "${FMT_INC_DIR} /fmt" )
494- endif ()
495- if (FMT_MODULE AND FMT_USE_CMAKE_MODULES)
496- list (APPEND INSTALL_FILE_SET FILE_SET fmt_module DESTINATION "${FMT_INC_DIR} /fmt" )
446+ if (FMT_USE_CMAKE_MODULES)
447+ set (INSTALL_FILE_SET FILE_SET fmt DESTINATION ${FMT_INC_DIR} /fmt)
448+ endif ()
497449 endif ()
498450
499451 # Install the library and headers.
@@ -502,7 +454,7 @@ if (FMT_INSTALL)
502454 EXPORT ${targets_export_name}
503455 LIBRARY DESTINATION ${FMT_LIB_DIR}
504456 ARCHIVE DESTINATION ${FMT_LIB_DIR}
505- PUBLIC_HEADER DESTINATION " ${FMT_INC_DIR} /fmt"
457+ PUBLIC_HEADER DESTINATION ${FMT_INC_DIR} /fmt
506458 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
507459 ${INSTALL_FILE_SET} )
508460
0 commit comments