32

when I use cmake in Release mode I have the following binary:

64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=485ac09b0a3aa879f88b7f5db6c00ea8d8e1eaf6, not stripped

I want the binary to be stripped. How can I say to cmake in a clean way to add the -s option to my compiler to make it stripped?

Why did the Default Release mode not strip my binary?

Fractale
  • 1,503
  • 3
  • 19
  • 34
  • 7
    Note that when you install a CMake project via `cmake --install`, you can provide the `--strip` argument that will strip everything upon installation. Doing things this way is typically much cleaner. You shouldn't deploy from the build folder, anyway, since the RPATHs will be messed up. – Alex Reinking Feb 22 '22 at 22:09
  • 1
    Yes `--strip` is the standard way to do it. – abu_bua Nov 25 '22 at 02:25

4 Answers4

29

Cleanest possible way is to modify CFLAGS or CXXFLAGS (depending on C or C++ code)

set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")

But there is one more hack if you do not want to change your build system (figuring out exact place where to put above lines might be tricky). You may just use strip as standalone application, like:

strip -s a.out

and do this after executable is ready to release as a post-build step. I found this way cleaner, then disturbing compiler flags.

Konstantin Vladimirov
  • 6,791
  • 1
  • 27
  • 36
  • 3
    Instead of altering you files, you can also pass `-DCMAKE_C_FLAGS="-s"` to the CMake call. – usr1234567 Jul 30 '16 at 17:44
  • 2
    Agree. Better -DCMAKE_C_FLAGS_RELEASE if you want to strip only release build. But this might be dangerous if cmake build overwrites flags instead of adding to them (regular case for custom builds). – Konstantin Vladimirov Jul 30 '16 at 18:23
  • Copy-pasted that 2 lines into my CMakeLists.txt. Makes no difference. Meanwhile a standalone /usr/bin/strip reduced the binary size to 55% of the original. – Soonts Oct 18 '17 at 19:26
  • 3
    This doesn't work if you link to library with debug symbols. It is better to strip on link, not in CXX. – Nikolay Shmyrev Jan 29 '20 at 21:18
  • You don't need this for MSVS. With Visual C++ (and other Microsoft compilers) on Windows, symbols aren't part of the binaries. Instead, they are stored in separate files called "Program Database" files (.pdb files). – Konstantin Vladimirov Jun 08 '21 at 16:04
  • Work well on gcc but not on Clang , because it doesn't have `-s` :( For compiler independent solution, check [here](https://stackoverflow.com/questions/53692348/cmake-platform-independent-binary-stripping-for-release-builds) – KuhakuPixel Mar 26 '23 at 02:07
  • One positive to @Dmitry's answer is that this argument (-s) is only added to the link stage. Meaning, by adding it to the C or CXX flags, every source file that is compiling will have these new flags. This doesn't happen when you use add_link_options. I didn't test, but this might help the situation with Clang, too. This might also address the other comment about stripping on link not in CXX. – Panda Jun 30 '23 at 14:48
25

You can try

set_target_properties(TARGET_NAME PROPERTIES LINK_FLAGS_RELEASE -s)
vok1980
  • 504
  • 5
  • 14
  • 2
    This is better than just setting the compiler flags as this affects only the desired target not all targets – وليد تاج الدين Jan 13 '21 at 11:29
  • @وليدتاجالدين - it is actually _much worse_ since it locks your project into compilers that understand the `-s` flag with the same meaning as you intended. – Alex Reinking Feb 22 '22 at 22:08
  • @AlexReinking - I mean better than the accepted answer - for my case that doesn't need to strip all the targets - as the accepted answer is already using the 's' flag. I think that your comment on the question will be better for stripping all the targets. – وليد تاج الدين Mar 03 '22 at 20:24
10

Using add_link_options() or set_target_properties() to add -s should work fine, additionally, CMake creates an install/strip target which also could be used for striping the binary if you have at least one install() command for your target (reference).

Example:

$ cmake --build . --config Release --target install/strip
Gary Wang
  • 340
  • 4
  • 13
7

This works fine:

add_link_options($<$<CONFIG:RELEASE>:-s>)
Dmitry
  • 664
  • 8
  • 8