10

I'm building a third-party CMake-based C++ project.

Building the project in release mode only takes a couple of seconds. The linking stage takes less than a second (when make prints Linking CXX executable myproject.exe).

Building in debug mode takes more than a minute. Most of this time is spent linking the executable. This happens even during subsequent builds after minimal changes to the code.

The difference to the release mode seems to be the -g option vs. the -O3 -DNDEBUG options. Is this behavior expected? I've worked on similar sized projects before (~18k LOC), but I've never experienced such a big difference in compile time between debug and release modes.

This takes 50 seconds:

C:\msys64\mingw64\bin\g++.exe -std=c++0x -Wall -Wextra -Wpointer-arith -Wcast-align -fstrict-aliasing -Wno-unused-local-typedefs -fvisibility- inlines-hidden -march=native -g -Wl,--whole-archive CMakeFiles\myproject.dir/objects.a -Wl,--no-whole-archive -o myproject.exe -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles\myproject.dir\linklibs.rsp

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jawap
  • 2,463
  • 3
  • 28
  • 46
  • Debug information can be quite large. Also, I think that the `-NDEBUG` option you mention is actually `-DNDEBUG` which is the `-D` preprocessor option to define a macro. – Some programmer dude Nov 08 '17 at 15:06
  • @Someprogrammerdude You're right, I updated my post. I still find it weird that the project takes over a minute to compile no matter if it's a clean build or a rebuild. – Jawap Nov 08 '17 at 15:45
  • 3
    @Jawap Is it possible that omitting `NDEBUG` enables _lots of code_ in some generic header? – yugr Nov 10 '17 at 17:10
  • @Jawap Please post your compiler/linker versions. – yugr Nov 10 '17 at 17:17
  • Another suspicious thing is presence of `whole-archive` flag. Typically it is used as a workaround to prevent linker from throwing various global objects (used to to self-register stuff for example) away. – user7860670 Nov 11 '17 at 13:47
  • What's your binutils version? – Florian Weimer Nov 11 '17 at 16:16
  • https://stackoverflow.com/questions/37327526/how-to-speed-up-compile-time-of-my-cmake-enabled-c-project – sailfish009 Nov 12 '17 at 10:52
  • Can't you enable incremental linking ? (-r) It should speed up at least incremental build. – sandwood Nov 14 '17 at 15:28
  • Some frameworks will behind the scene enable much more functions in Debug than in Release, Qt for example (Q_ASSERT being dropt in Release) – sandwood Nov 14 '17 at 15:30
  • Can [`-fvisibility-inlines-hidden`](https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#index-fvisibility-inlines-hidden) really be split over two lines like that (space in front of the backslash)? – Peter Mortensen Oct 31 '22 at 20:18
  • What are the three `-Wl` options supposed to do? – Peter Mortensen Nov 03 '22 at 21:19
  • There is a forward slash preceding "objects.a" (all the other are backslashes). – Peter Mortensen Nov 03 '22 at 21:20

1 Answers1

6

Unfortunately, link times for large projects can be quite slow, especially in debug mode. Things that usually help are

  • splitting a project to shared libraries (that's done, e.g., by LLVM developers)
  • linking on SSD (or tmpfs)
  • using the Gold linker instead of the default BFD linker (or maybe even LLD as it's getting more stable)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
yugr
  • 19,769
  • 3
  • 51
  • 96
  • 2
    There's also `LLD`, the LLVM linker, which is probably the fastest linker around and should be quite mature: https://lld.llvm.org – valiano Nov 13 '17 at 18:53
  • @valiano Thanks, I didn't mention it because it's quite new (it took Gold several years to be able to link world). – yugr Nov 13 '17 at 18:58
  • 1
    LLD is actually pretty usable. For our project (600MB ELF with debug symbols), it is ~8x faster than BFD ld, and 3x faster than gold (creates the 600MB ELF in 3 seconds!). – geza Jun 26 '18 at 10:20