[PATCH v2 1/6] Add some gcc/ld optimizations and magic

David Herrmann dh.herrmann at gmail.com
Sun Sep 1 08:45:04 PDT 2013

There are several gcc/ld flags that optimize size and performance without
requiring explicit code changes. In no particular order, this adds:
 - gcc -pipe to avoid temporary files and use pipes during compilation
 - gcc -fno-common avoids putting uninitialized global variables not
   marked as "extern" into a common section. This catches compilation
   errors if we didn't mark global variables explicitly as "extern".
 - gcc -fno-strict-aliasing allows us to use unions for some binary magic.
   Otherwise, -O2 might assume that two different types never point at the
   same memory. We currently don't rely on this but it's common practice
   so avoid any non-obvious runtime errors later.
 - gcc -ffunction-sections and -fdata-sections put each function and
   variable into a separate section. This enables ld's --gc-sections to
   drop any unused sections (sections which aren't referenced from an
   exported section). This is very useful to avoid putting dead code into
   DSOs. We can now link any helper function into libevdev and the linker
   removes all of them if they're unused.
 - gcc -fstack-protector adds small stack-corruption protectors in
   functions which have big buffers on the stack (>8bytes). If the
   stack-protectors are corrupted, the process is aborted. This is highly
   useful to debug stack-corruption issues which often are nearly
   impossible to catch without this.
 - ld --as-needed drops all linked libraries that are not actually
   required by libevdev. So we can link to whatever we want and the linker
   will drop everything which is not actually used.
 - ld -z now, resolve symbols during linking, not during runtime.
 - ld -z relro, add relocation-read-only section. This allows to put
   read-only global variables and alike into a read-only section. This is
   useful for variables that need a relocation and thus cannot be
   explicitly put into a read-only section. This option tells the linker
   to mark them read-only after relocations are done. (that's why -z now
   makes sense in combination with this)

All of these options are common in other open-source projects, including
systemd and weston. Don't ask me why they are not marked as default..

Signed-off-by: David Herrmann <dh.herrmann at gmail.com>
 configure.ac         | 2 +-
 libevdev/Makefile.am | 9 ++++++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 78ab380..a88f7c0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -42,7 +42,7 @@ AM_CONDITIONAL(BUILD_TESTS, [test "x$HAVE_CHECK" = "xyes"])
 if test "x$GCC" = "xyes"; then
-	GCC_CFLAGS="-Wall -Wextra -Wno-unused-parameter -g -Wstrict-prototypes -Wmissing-prototypes -fvisibility=hidden"
+	GCC_CFLAGS="-Wall -Wextra -Wno-unused-parameter -g -Wstrict-prototypes -Wmissing-prototypes -fvisibility=hidden -pipe -fno-common -fno-strict-aliasing -ffunction-sections -fdata-sections -fstack-protector -fno-strict-aliasing -fdiagnostics-show-option -fno-common"
diff --git a/libevdev/Makefile.am b/libevdev/Makefile.am
index 5ebbd42..64adf58 100644
--- a/libevdev/Makefile.am
+++ b/libevdev/Makefile.am
@@ -11,7 +11,14 @@ libevdev_la_SOURCES = \
                    libevdev-uinput-int.h \
-libevdev_la_LDFLAGS = -version-info $(LIBEVDEV_LT_VERSION) -export-symbols-regex '^libevdev_' $(GCOV_LDFLAGS)
+libevdev_la_LDFLAGS = \
+	-version-info $(LIBEVDEV_LT_VERSION) \
+	-export-symbols-regex '^libevdev_' \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,-z,relro \
+	-Wl,-z,now
 libevdevincludedir = $(includedir)/libevdev-1.0/libevdev
 libevdevinclude_HEADERS = libevdev.h libevdev-uinput.h

More information about the Input-tools mailing list