[libfmt] Build as a DLL on Windows and Mac OS X.

This significantly reduces the total size. fmt-11.dll's Release build
size is 128 KiB, and it cuts between 16-64 KiB from binaries that use it.

Total size of EXEs and DLLs, with amiiboc.exe and libgnuintl-8.dll,
but without test executables or PDBs:
[MSVC 2022 v17.6.5, Release build]

- Total size of EXEs and DLLs with header-only: 4,332,032
- Total size of EXEs and DLLs with fmt-11.dll:  4,161,536
- Difference:                                    -170,496

With test executables:

- Total size of EXEs and DLLs with header-only: 9,716,224
- Total size of EXEs and DLLs with fmt-11.dll:  7,907,840
- Difference:                                  -1,808,384

TODO: Add Delay-Load checks for fmt-11.dll to e.g. rpcli and the
Win32 UI frontend. (amiiboc and unit tests don't need it.)
This commit is contained in:
David Korth 2025-01-23 00:36:34 -05:00
parent bd19196ea6
commit b11f9fa4c2
5 changed files with 36 additions and 8 deletions

View File

@ -31,7 +31,7 @@ IF(USE_INTERNAL_FMT)
SET(HAVE_Fmt 1)
SET(Fmt_VERSION 11.1.2 CACHE INTERNAL "libfmt version" FORCE)
# FIXME: When was it changed from LIBRARY to LIBRARIES?
IF(0 AND (WIN32 OR APPLE)) # TODO: Use DLLs on Windows and Mac OS X.
IF(WIN32 OR APPLE)
# Using DLLs on Windows and Mac OS X.
SET(USE_INTERNAL_FMT_DLL ON)
SET(Fmt_LIBRARY fmt::fmt CACHE INTERNAL "libfmt library" FORCE)

19
extlib/CMakeLists.txt vendored
View File

@ -416,12 +416,19 @@ SET_EXTLIB_PROPERTIES(microtar)
IF(USE_INTERNAL_FMT)
# Use the internal copy of libfmt.
# TODO: Build DLLs on Windows and Mac OS X.
# For now, a header-only build will be used.
SET(SKIP_INSTALL_LIBRARIES ON)
SET(SKIP_INSTALL_ALL ON)
SET(BUILD_SHARED_LIBS OFF)
SET(BUILD_STATIC_LIBS ON)
# On Windows and Mac OS X, this will build DLLs.
# On other systems, this will be statically-linked.
IF(WIN32 OR APPLE)
SET(SKIP_INSTALL_LIBRARIES OFF)
SET(SKIP_INSTALL_ALL ON)
SET(BUILD_SHARED_LIBS ON)
SET(BUILD_STATIC_LIBS OFF)
ELSE()
SET(SKIP_INSTALL_LIBRARIES ON)
SET(SKIP_INSTALL_ALL ON)
SET(BUILD_SHARED_LIBS OFF)
SET(BUILD_STATIC_LIBS ON)
ENDIF()
SET(FMT_PEDANTIC OFF)
SET(FMT_WERROR OFF)

View File

@ -338,7 +338,8 @@ set(FMT_DEBUG_POSTFIX d CACHE STRING "Debug library postfix.")
set_target_properties(fmt PROPERTIES
VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR}
PUBLIC_HEADER "${FMT_HEADERS}"
DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX}"
# rom-properties: DEBUG_POSTFIX will be set next.
#DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX}"
# Workaround for Visual Studio 2017:
# Ensure the .pdb is created with the same name and in the same directory
@ -348,12 +349,28 @@ set_target_properties(fmt PROPERTIES
COMPILE_PDB_NAME "fmt"
COMPILE_PDB_NAME_DEBUG "fmt${FMT_DEBUG_POSTFIX}")
IF(WIN32)
# rom-properties: On Windows, include the SOVERSION as part of the POSTFIX for both DEBUG and RELEASE.
SET_TARGET_PROPERTIES(fmt PROPERTIES
DEBUG_POSTFIX "-${CPACK_PACKAGE_VERSION_MAJOR}${FMT_DEBUG_POSTFIX}"
RELEASE_POSTFIX "-${CPACK_PACKAGE_VERSION_MAJOR}"
)
ELSE(WIN32)
# rom-properties: On other systems, just set DEBUG_POSTFIX.
SET_TARGET_PROPERTIES(fmt PROPERTIES
DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX}"
)
ENDIF(WIN32)
# Set FMT_LIB_NAME for pkg-config fmt.pc. We cannot use the OUTPUT_NAME target
# property because it's not set by default.
set(FMT_LIB_NAME fmt)
# rom-properties: Handled above.
IF(0) # rom-properties
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(FMT_LIB_NAME ${FMT_LIB_NAME}${FMT_DEBUG_POSTFIX})
endif ()
ENDIF(0) # rom-properties
if (BUILD_SHARED_LIBS)
target_compile_definitions(fmt PRIVATE FMT_LIB_EXPORT INTERFACE FMT_SHARED)

View File

@ -75,6 +75,7 @@ static const char *const dll_whitelist[] = {
"minilzo" DEBUG_SUFFIX ".dll",
"libgnuintl-8.dll",
"minizip" DEBUG_SUFFIX ".dll",
"fmt-11" DEBUG_SUFFIX ".dll",
};
/**

View File

@ -23,6 +23,9 @@ IF(MSVC)
IF(NOT USE_INTERNAL_MINIZIP OR USE_INTERNAL_MINIZIP_DLL)
SET(DL_DLLS ${DL_DLLS} minizip)
ENDIF(NOT USE_INTERNAL_MINIZIP OR USE_INTERNAL_MINIZIP_DLL)
IF(NOT USE_INTERNAL_FMT OR USE_INTERNAL_FMT_DLL)
SET(DL_DLLS ${DL_DLLS} fmt-11)
ENDIF(NOT USE_INTERNAL_FMT OR USE_INTERNAL_FMT_DLL)
SET(DL_DEBUG_FLAGS "/ignore:4199")
SET(DL_RELEASE_FLAGS "/ignore:4199")