# Compile flags in the linking command for link time optimization

**URL:** https://discourse.cmake.org/t/compile-flags-in-the-linking-command-for-link-time-optimization/9413
**Category:** Usage
**Tags:** os:linux, gen:ninja
**Created:** [November 11, 2023, 4:25pm UTC](https://discourse.cmake.org/t/compile-flags-in-the-linking-command-for-link-time-optimization/9413 "2023-11-11T16:25:31Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![One\_Cable5781](https://discourse.cmake.org/user_avatar/discourse.cmake.org/one_cable5781/32/3975_2.png) [@One\_Cable5781](https://discourse.cmake.org/u/One_Cable5781)
#### Post date: [November 11, 2023, 4:25pm UTC](https://discourse.cmake.org/t/compile-flags-in-the-linking-command-for-link-time-optimization/9413/1 "2023-11-11T16:25:31Z")

</div>

According to [gcc documentation for link time optimization](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-flto):

> It is recommended that you compile all the files participating in the same link with the same options and also specify those options at link time

I specify in `CML.txt` the following:

`set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)`  
`set(CMAKE_VERBOSE_MAKEFILE on)`

to see the actual emitted compile and linking command. My compile commands are like so [snipped for brevity]:

```auto
[33%] Building CXX object CMakeFiles/CMakeProject.dir/code/main.cpp.o

/usr/bin/c++ -O3 -flto -fno-fat-lto-objects -fPIE -m64 -fno-common -fPIC -fno-strict-aliasing -fexceptions -fopenmp -DNDEBUG -o CMakeFiles/CMakeProject.dir/code/main.cpp.o -c code/main.cpp

[66%] Building CXX object CMakeFiles/CMakeProject.dir/code/impl.cpp.o

/usr/bin/c++ -O3 -flto -fno-fat-lto-objects -fPIE -m64 -fno-common -fPIC -fno-strict-aliasing -fexceptions -fopenmp -DNDEBUG -o CMakeFiles/CMakeProject.dir/code/impl.cpp.o -c code/impl.cpp

```

The emitted linking command is like so:

```auto
[100%] Linking CXX executable CMakeProject
 
/snap/cmake/1336/bin/cmake -E cmake_link_script CMakeFiles/CMakeProject.dir/link.txt --verbose=1
 
/usr/bin/c++ -O3 -flto -fno-fat-lto-objects code/main.cpp.o code/impl.cpp.o -o CMakeProject -Wl,-rpath,/usr/local/lib -lm -lpthread -ldl

```

In particular, unlike as suggested over in the GCC site, I do not see flags such as `-fPIC`, etc., which feature in the compile stage appear in the linking stage. Although, I do see that both the linker and the compiler make use of `-flto`.

Is this because some of the flags that appear in the compile stage are not relevant to the linking stage? Is there CMake documentation of which flags are applicable to both the linker and the compiler and which are not? Clearly, CMake should be using this information to generate the right linking command for inter procedural/link time optimization.

---

<div class="post-metadata">

### Author: ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)
#### Post date: [November 11, 2023, 4:45pm UTC](https://discourse.cmake.org/t/compile-flags-in-the-linking-command-for-link-time-optimization/9413/2 "2023-11-11T16:45:55Z")

</div>

Regarding `POSITION_INDEPENDENT_CODE`, to get correct flags at link step, you have to explicitly ask for by using [CheckPIESupported](https://cmake.org/cmake/help/latest/module/CheckPIESupported.html) module.  
The reason for a such approach is the cost of a such test. It is too costly to be done at configuration, which would impact **all** users.

For `-flto` and others flags, involved in inter-procedural optimization, they are defined in both steps (compilation and link) because `CMake` offers a high-level concept (i.e. `INTERPROCEDURAL_OPTIMIZATION` target property) to manage this.

For the other flags, I am afraid it is your responsibility to set them for the link step (using [target\_link\_options()](https://cmake.org/cmake/help/latest/command/add_link_options.html) command because `CMake` has no high-level concept for them so is not aware of the semantics attached to them (in particular what are the interaction between compilation and link steps).

---

<div class="post-metadata">

### Author: ![One\_Cable5781](https://discourse.cmake.org/user_avatar/discourse.cmake.org/one_cable5781/32/3975_2.png) [@One\_Cable5781](https://discourse.cmake.org/u/One_Cable5781)
#### Post date: [November 11, 2023, 5:01pm UTC](https://discourse.cmake.org/t/compile-flags-in-the-linking-command-for-link-time-optimization/9413/3 "2023-11-11T17:01:23Z")

</div>

[CMake documentation on IPO](https://cmake.org/cmake/help/latest/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.html) states this:

> If set to true, enables interprocedural optimizations if they are known [`to be supported`](https://cmake.org/cmake/help/latest/module/CheckIPOSupported.html#module:CheckIPOSupported) by the compiler.

Usage of the word “enable” in the documentation is my source of confusion. If I understand correctly, what the option actually does is that when the user sets this option to true, and the compiler supports it, the `-flto` flag is added at the compile as well as the link stage. That is it. To actually generate an executable that has benefitted from IPO, it is still the user’s responsibility to additionally manually figure out which others flags are to be added to the linker stage that also feature in the compile stage as recommended by GCC.

If I have understood this correctly based on your response, this is useful to know because it appears to me that the wording in the documentation should make this explicit: setting the option to true does not really “enable” IPO in that the resulting executable/target can be produced using IPO. It _merely_ adds the flag `-flto` to the compiler and the linker.

Thank you for the response.
