diff options
author | Martin Matuška <martin@matuska.org> | 2022-01-03 12:07:13 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-03 12:07:13 +0100 |
commit | dd733f5c25efcc727c38949811e597d196a003f7 (patch) | |
tree | 89f84668ac88e22d9e732b525bcffa16d79c70e7 | |
parent | 38db08b16698e73c22b131cddd68658b80a43845 (diff) | |
parent | fc0758237548328941fa7a9699510d6f357896ed (diff) | |
download | libarchive-dd733f5c25efcc727c38949811e597d196a003f7.tar.gz |
Merge pull request #1625 from evelikov/gc-sections
Instrument gcc/clang to discard unused code during link
-rw-r--r-- | CMakeLists.txt | 44 | ||||
-rw-r--r-- | Makefile.am | 8 | ||||
-rw-r--r-- | configure.ac | 16 |
3 files changed, 45 insertions, 23 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index c5c22a24..1e1ff575 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,8 @@ # CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR) +if(POLICY CMP0065) + cmake_policy(SET CMP0065 NEW) #3.4 don't use `-rdynamic` with executables +endif() if(POLICY CMP0074) cmake_policy(SET CMP0074 NEW) #3.12.0 `find_package()`` uses ``<PackageName>_ROOT`` variables. endif() @@ -96,24 +99,8 @@ endif () # Especially for early development, we want to be a little # aggressive about diagnosing build problems; this can get # relaxed somewhat in final shipping versions. -IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$") - SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security") - ################################################################# - # Set compile flags for all build types. - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security") - if (ENABLE_WERROR) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") - endif () - ################################################################# - # Set compile flags for debug build. - # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug" - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wextra") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wunused") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wmissing-prototypes") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wcast-qual") -ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$") -IF (CMAKE_C_COMPILER_ID MATCHES "^Clang$") +IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR + CMAKE_C_COMPILER_ID MATCHES "^Clang$") SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security") ################################################################# # Set compile flags for all build types. @@ -130,7 +117,26 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^Clang$") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wmissing-prototypes") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wcast-qual") -ENDIF (CMAKE_C_COMPILER_ID MATCHES "^Clang$") + # Ideally this will be a compile/link time check, yet there's no obvious way + # how considering how old our minimum required cmake version is. The official + # cmake.org side does not host the manual pages even. Normally we can use + # either of the following two, yet neither is supported as of 3.0.2 + # - check_linker_flag - does not exist + # - try_compile - does not support linker flags + # + # The CI fails with this on MacOS + IF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin") + # Place the functions and data into separate sections, allowing the linker + # to garbage collect the unused ones. + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections") + # Printing the discarded section is "too much", so enable on demand. + #SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Wl,--print-gc-sections") + #SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -Wl,--print-gc-sections") + ENDIF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin") +ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR + CMAKE_C_COMPILER_ID MATCHES "^Clang$") IF (CMAKE_C_COMPILER_ID MATCHES "^XL$") SET(CMAKE_C_COMPILER "xlc_r") SET(CMAKE_REQUIRED_FLAGS "-qflag=e:e -qformat=sec") diff --git a/Makefile.am b/Makefile.am index cc8ae29c..9469cf69 100644 --- a/Makefile.am +++ b/Makefile.am @@ -284,7 +284,7 @@ endif # -no-undefined marks that libarchive doesn't rely on symbols # defined in the application. This is mandatory for cygwin. -libarchive_la_LDFLAGS= -no-undefined -version-info $(ARCHIVE_LIBTOOL_VERSION) +libarchive_la_LDFLAGS= -no-undefined -version-info $(ARCHIVE_LIBTOOL_VERSION) $(GC_SECTIONS) libarchive_la_LIBADD= $(LTLIBICONV) # Manpages to install @@ -1024,7 +1024,7 @@ endif bsdtar_LDADD= libarchive.la libarchive_fe.la $(LTLIBICONV) bsdtar_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdtar_ccstatic) $(PLATFORMCPPFLAGS) -bsdtar_LDFLAGS= $(bsdtar_ldstatic) +bsdtar_LDFLAGS= $(bsdtar_ldstatic) $(GC_SECTIONS) bsdtar_EXTRA_DIST= \ tar/bsdtar.1 \ @@ -1190,7 +1190,7 @@ endif bsdcpio_LDADD= libarchive_fe.la libarchive.la $(LTLIBICONV) bsdcpio_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdcpio_ccstatic) $(PLATFORMCPPFLAGS) -bsdcpio_LDFLAGS= $(bsdcpio_ldstatic) +bsdcpio_LDFLAGS= $(bsdcpio_ldstatic) $(GC_SECTIONS) bsdcpio_EXTRA_DIST= \ cpio/bsdcpio.1 \ @@ -1344,7 +1344,7 @@ endif bsdcat_LDADD= libarchive_fe.la libarchive.la $(LTLIBICONV) bsdcat_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdcat_ccstatic) $(PLATFORMCPPFLAGS) -bsdcat_LDFLAGS= $(bsdcat_ldstatic) +bsdcat_LDFLAGS= $(bsdcat_ldstatic) $(GC_SECTIONS) bsdcat_EXTRA_DIST= \ cat/bsdcat.1 \ diff --git a/configure.ac b/configure.ac index 85868ade..f9fe624e 100644 --- a/configure.ac +++ b/configure.ac @@ -542,6 +542,22 @@ fi # Checks for supported compiler flags AX_APPEND_COMPILE_FLAGS([-Wall -Wformat -Wformat-security]) +# Place the functions and data into separate sections, allowing the linker +# to garbage collect the unused ones. +save_LDFLAGS=$LDFLAGS +LDFLAGS="$LDFLAGS -Wl,--gc-sections" +AC_MSG_CHECKING([whether ld supports --gc-sections]) +AC_LINK_IFELSE( + [AC_LANG_SOURCE([static char UnusedFunc() { return 5; } int main() { return 0;}])], + [AC_MSG_RESULT([yes]) + GC_SECTIONS="-Wl,--gc-sections"; + AX_APPEND_COMPILE_FLAGS([-ffunction-sections -fdata-sections])], + [AC_MSG_RESULT([no]) + GC_SECTIONS="";]) +LDFLAGS=$save_LDFLAGS + +AC_SUBST(GC_SECTIONS) + # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST # la_TYPE_UID_T defaults to "int", which is incorrect for MinGW |