cmake: enable -fdata/function-sections and --gc-sections

The former two split the functions and data into separate sections
within the object file. Which makes it easier for the latter to properly
garbage collect and discard unused sections. For example

   text	   data	    bss	    dec	    hex	filename
 208268	   2056	   4424	 214748	  346dc	bsdcat -- before
  93396	   1304	   4360	  99060	  182f4	bsdcat -- after
1059167	  12112	  24176	1095455	 10b71f	bsdcpio -- before
1002538	   7320	  23984	1033842	  fc672	bsdcpio -- after
1093676	  14248	   6608	1114532	 1101a4	bsdtar -- before
1062231	  14176	   6416	1082823	 1085c7	bsdtar -- after
1097259	  15032	   6408	1118699	 1111eb	libarchive.so.18 -- before
1095675	  14992	   6216	1116883	 110ad3	libarchive.so.18 -- after

Note:
This is enabled only with gcc/clang on non-Mac platforms. Ideally we'll
have a compile-time check, albeit that seems impossible with our ancient
cmake requirement.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
This commit is contained in:
Emil Velikov committed 2021-11-21 19:17:33 +00:00
1 parent 1b50bca40b
commit 3beea10fce
1 file changed
+18
+18
View File
@@ -117,6 +117,24 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
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")
# 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$")