[systemd-devel] [PATCH] Compiler and linker flags to reduce binary size.

Gustavo Sverzut Barbieri barbieri at profusion.mobi
Thu Sep 30 11:58:37 PDT 2010


Reduce number of exported symbols with -fvisibility=hidden by default,
this is safe as we're not generating and loadable library and our
binaries should have no exported symbol other than main(). This alone
reduces around 4kb per binary.

It will also request GCC to emit every function and data variable in
its own section, then request the linker to remove unused
sections. This reduces the size of utility tools
(/lib/systemd/systemd-*) by half or even more (in my system some
binaries went from 84kb to 32kb).

m4/attributes.m4 was modified to provide CC_CHECK_LDFLAGS_APPEND() in
the same lines as CC_CHECK_CFLAGS_APPEND().
---
 configure.ac     |   11 +++++++++++
 m4/attributes.m4 |   41 ++++++++++++++++++++++++++++++++++++-----
 2 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index 753adc5..9d64130 100644
--- a/configure.ac
+++ b/configure.ac
@@ -85,9 +85,20 @@ CC_CHECK_CFLAGS_APPEND([ \
         -Wp,-D_FORTIFY_SOURCE=2 \
         -ffast-math \
         -fno-common \
+        -fvisibility=hidden \
+        -ffunction-sections \
+        -fdata-sections \
         -fdiagnostics-show-option \
         -fno-strict-aliasing])
 
+CC_CHECK_LDFLAGS_APPEND([ \
+        -fvisibility=hidden \
+        -ffunction-sections \
+        -fdata-sections \
+        -Wl,--as-needed \
+        -Wl,--gc-sections \
+        -Wl,--print-gc-sections])
+
 LT_PREREQ(2.2)
 LT_INIT
 
diff --git a/m4/attributes.m4 b/m4/attributes.m4
index 3bf96a3..15284a6 100644
--- a/m4/attributes.m4
+++ b/m4/attributes.m4
@@ -81,12 +81,11 @@ AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [
   done
 ])
 
-dnl Check if the flag is supported by linker (cacheable)
-dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
+dnl Check if the flag is supported by compiler
+dnl CC_CHECK_LDFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
 
-AC_DEFUN([CC_CHECK_LDFLAGS], [
-  AC_CACHE_CHECK([if $CC supports $1 flag],
-    AS_TR_SH([cc_cv_ldflags_$1]),
+AC_DEFUN([CC_CHECK_LDFLAGS_SILENT], [
+  AC_CACHE_VAL(AS_TR_SH([cc_cv_ldflags_$1]),
     [ac_save_LDFLAGS="$LDFLAGS"
      LDFLAGS="$LDFLAGS $1"
      AC_LINK_IFELSE([int main() { return 1; }],
@@ -99,6 +98,38 @@ AC_DEFUN([CC_CHECK_LDFLAGS], [
     [$2], [$3])
 ])
 
+dnl Check if the flag is supported by compiler (cacheable)
+dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
+
+AC_DEFUN([CC_CHECK_LDFLAGS], [
+  AC_CACHE_CHECK([if $CC supports $1 flag],
+    AS_TR_SH([cc_cv_ldflags_$1]),
+    CC_CHECK_LDFLAGS_SILENT([$1]) dnl Don't execute actions here!
+  )
+
+  AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],
+    [$2], [$3])
+])
+
+dnl CC_CHECK_LDFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])
+dnl Check for LDFLAG and appends them to LDFLAGS if supported
+AC_DEFUN([CC_CHECK_LDFLAG_APPEND], [
+  AC_CACHE_CHECK([if $CC supports $1 flag],
+    AS_TR_SH([cc_cv_ldflags_$1]),
+    CC_CHECK_LDFLAGS_SILENT([$1]) dnl Don't execute actions here!
+  )
+
+  AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],
+    [LDFLAGS="$LDFLAGS $1"; DEBUG_LDFLAGS="$DEBUG_LDFLAGS $1"; $2], [$3])
+])
+
+dnl CC_CHECK_LDFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not])
+AC_DEFUN([CC_CHECK_LDFLAGS_APPEND], [
+  for flag in $1; do
+    CC_CHECK_LDFLAG_APPEND($flag, [$2], [$3])
+  done
+])
+
 dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for
 dnl the current linker to avoid undefined references in a shared object.
 AC_DEFUN([CC_NOUNDEFINED], [
-- 
1.7.2.2



More information about the systemd-devel mailing list