Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

INTERPROCEDURAL_OPTIMIZATION not set even if check_ipo_supported() works in CMake

I've the following project in CMake 3.14.0, that builds a project for Visual Studio 2017 64 bit generator (minimum version is 3.10.0 because other developer can have previous versions of CMake, but greater than 3.9.0):

cmake_minimum_required (VERSION 3.10.0)

project (data)

add_definitions (-DDATA_EXPORTS)

include_directories (${CMAKE_CURRENT_SOURCE_DIR}/..)

set (PROJECT_SRC
  Player.cpp
  LLA.cpp
  Attitude.cpp
  )

add_library (${PROJECT_NAME} SHARED ${PROJECT_SRC})
target_compile_features (${PROJECT_NAME} PUBLIC cxx_std_17)
# Enable IPO
include(CheckIPOSupported)
check_ipo_supported(RESULT iporesult)
if(iporesult)
  message (STATUS "IPO supported for project ${PROJECT_NAME}")
  set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()

I've added some commands for adding support for LTO in Visual Studio. I've seen that I must to check the support for IPO and, if it's ok, I must do set the INTERPROCEDURAL_OPTIMIZATION property, that's what I did

When I run the project I obtain the following message (I'm also using vcpkg and that's the reason for the first row):

[cmake] IPO supported for project data
...
[cmake] CMake Warning (dev) at D:/Projects/vcpkg/scripts/buildsystems/vcpkg.cmake:198 (_add_library):
[cmake]   Policy CMP0069 is not set: INTERPROCEDURAL_OPTIMIZATION is enforced when
[cmake]   enabled.  Run "cmake --help-policy CMP0069" for policy details.  Use the
[cmake]   cmake_policy command to set the policy and suppress this warning.
[cmake] 
[cmake]   INTERPROCEDURAL_OPTIMIZATION property will be ignored for target 'data'.
[cmake] Call Stack (most recent call first):
[cmake]   src/Data/CMakeLists.txt:18 (add_library)
[cmake] This warning is for project developers.  Use -Wno-dev to suppress it.

As far as I've seen, the link time optimization it's not enabled for the project. I've also opened the project in Visual Studio and I've checked the command line of the project, and that's the result for the building:

/GS /TP /W3 /Zc:wchar_t /I"M:\project\src\Data\.." /Zi /Gm- /Od /Ob0 /Fd"data.dir\Debug\vc141.pdb" /Zc:inline /fp:precise /D "WIN32" /D "_WINDOWS" /D "DATA_EXPORTS" /D "CMAKE_INTDIR=\"Debug\"" /D "data_EXPORTS" /D "_WINDLL" /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /GR /Gd /MDd /std:c++17 /Fa"Debug/" /EHsc /nologo /Fo"data.dir\Debug\" /Fp"data.dir\Debug\data.pch" /diagnostics:classic

and for the linking

/OUT:"M:\project\build\vscode\build\bin\Debug\data.dll" /MANIFEST /NXCOMPAT /PDB:"M:/project/build/vscode/build/bin/Debug/data.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "comdlg32.lib" "advapi32.lib" /IMPLIB:"M:/project/build/vscode/build/lib/Debug/data.lib" /DEBUG /DLL /MACHINE:X64 /INCREMENTAL /PGD:"M:\project\build\vscode\build\bin\Debug\data.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"data.dir\Debug\data.dll.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1 

I don't see any flags for LTO.

I've run the command for the policy and that's the result:

cmake --help-policy CMP0069
CMP0069
-------

``INTERPROCEDURAL_OPTIMIZATION`` is enforced when enabled.

CMake 3.9 and newer prefer to add IPO flags whenever the
``INTERPROCEDURAL_OPTIMIZATION`` target property is enabled and
produce an error if flags are not known to CMake for the current compiler.
Since a given compiler may not support IPO flags in all environments in which
it is used, it is now the project's responsibility to use the
``CheckIPOSupported`` module to check for support before enabling the
``INTERPROCEDURAL_OPTIMIZATION`` target property.  This approach
allows a project to conditionally activate IPO when supported.  It also
allows an end user to set the ``CMAKE_INTERPROCEDURAL_OPTIMIZATION``
variable in an environment known to support IPO even if the project does
not enable the property.

Since CMake 3.8 and lower only honored ``INTERPROCEDURAL_OPTIMIZATION``
for the Intel compiler on Linux, some projects may unconditionally enable the
target property.  Policy ``CMP0069`` provides compatibility with such projects.

This policy takes effect whenever the IPO property is enabled.  The ``OLD``
behavior for this policy is to add IPO flags only for Intel compiler on Linux.
The ``NEW`` behavior for this policy is to add IPO flags for the current
compiler or produce an error if CMake does not know the flags.

This policy was introduced in CMake version 3.9.  CMake version
3.14.0 warns when the policy is not set and uses ``OLD`` behavior.
Use the ``cmake_policy()`` command to set it to ``OLD`` or ``NEW``
explicitly.

.. note::
  The ``OLD`` behavior of a policy is
  ``deprecated by definition``
  and may be removed in a future version of CMake.

Examples
^^^^^^^^

Behave like CMake 3.8 and do not apply any IPO flags except for Intel compiler
on Linux:

 cmake_minimum_required(VERSION 3.8)
 project(foo)

 # ...

 set_property(TARGET ... PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)

Use the ``CheckIPOSupported`` module to detect whether IPO is
supported by the current compiler, environment, and CMake version.
Produce a fatal error if support is not available:

 cmake_minimum_required(VERSION 3.9) # CMP0069 NEW
 project(foo)

 include(CheckIPOSupported)
 check_ipo_supported()

 # ...

 set_property(TARGET ... PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)

Apply IPO flags only if compiler supports it:

 cmake_minimum_required(VERSION 3.9) # CMP0069 NEW
 project(foo)

 include(CheckIPOSupported)

 # ...

 check_ipo_supported(RESULT result)
 if(result)
   set_property(TARGET ... PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
 endif()

Apply IPO flags without any checks.  This may lead to build errors if IPO
is not supported by the compiler in the current environment.  Produce an
error if CMake does not know IPO flags for the current compiler:

 cmake_minimum_required(VERSION 3.9) # CMP0069 NEW
 project(foo)

 # ...

 set_property(TARGET ... PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)

It seems that I'm using it in the right way.

What I don't understand is why the property is not applied if the command check_ipo_supported tells me another story.

What I'm doing wrong?

like image 278
Jepessen Avatar asked Jun 06 '19 07:06

Jepessen


2 Answers

You need to set policy:

https://cmake.org/cmake/help/git-stage/policy/CMP0069.html

cmake_policy(SET CMP0069 NEW) 
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
like image 122
Olga Krishtal Avatar answered Oct 12 '22 22:10

Olga Krishtal


Weird, I tried the code from question on Linux (NixOS 19.03, GCC) and it worked fine for me. I believe that you want to print this diagnostic message which you are currently swallowing. It might help towards solution. (It helped me, I was missing C++ compiler, and check_ipo_supported by default checks that both C and C++ IPO works.)

check_ipo_supported(RESULT result OUTPUT output)
if(result)
  set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
  message(WARNING "IPO is not supported: ${output}")
endif()

It's from https://cmake.org/cmake/help/v3.9/module/CheckIPOSupported.html

like image 44
user7610 Avatar answered Oct 13 '22 00:10

user7610