2

I'm enabling IPO (inter-procedural optimization) for a C compilation of mine, using CMake:

set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)

As expected, this causes an -flto compiler flag to be added. However, it also adds -fno-fat-lto-objects: That means that the resulting object file will only have intermediate code, rather than both properly-compiled and intermediate code; and that means that the linker must support my system compiler's intermediate representation and be IPO/LTO-aware.

I didn't ask for -fno-fat-lto-objects, nor did I want it. Can I get CMake to not add this option?

einpoklum
  • 118,144
  • 57
  • 340
  • 684

2 Answers2

4

I believe this is a CMake bug... which I have now filed:

The developers have simply made the incorrect assumption that this is what people want.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
2
if(CMAKE_C_COMPILER MATCHES "GNU")
   set(CMAKE_C_COMPILE_OPTIONS_IPO "-flto")
endif()

How to find it:

  1. Navigate to your CMake installation directory and to Modules, most of the stuff is there.

    • It's /usr/share/cmake/Modules on my Linux system
  2. Find the string or similar string that you are interested in

    • on my system, I do:

      $ grep fno-fat-lto-objects -r .
      ./Compiler/GNU.cmake:      list(APPEND __lto_flags -fno-fat-lto-objects)
      
  3. Navigate and inspect the resulting files, the context where the string is used:

       # '-flto' introduced since GCC 4.5:
       # * https://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Option-Summary.html (no)
       # * https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Option-Summary.html (yes)
       if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.5)
         set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
         set(__lto_flags -flto)
    
         if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.7)
           # '-ffat-lto-objects' introduced since GCC 4.7:
           # * https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Option-Summary.html (no)
           # * https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Option-Summary.html (yes)
           list(APPEND __lto_flags -fno-fat-lto-objects)
         endif()
    
         set(CMAKE_${lang}_COMPILE_OPTIONS_IPO ${__lto_flags})
    
  4. Come up with a workaround to implement custom behavior of such coe.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Also, `-flto=full` for later clang and `-flto` for earlier clang. – einpoklum Jan 21 '22 at 20:11
  • GNU.cmake is also executed by clang. Maybe change `if(CMAKE_C_COMPILER MATCHES "GNU")` to something like `if(CMAKE_C_COMPILE_OPTIONS_IPO MATCHES "-fno-fat-lto-objects")` then regex remove `-fno-fat-lto-objects` from it, or similar. – KamilCuk Jan 21 '22 at 20:13