Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WholeProgramOptimization in CMake

What can I do to enable WholeProgramOptimization from CMake ?

Here is what I tried:

  • I have CMake 3.10.2 installed
  • I have Visual Studio 2017 15.5.4 installed
  • I created a directory C:\Wpo
  • I created an empty directory C:\Wpo\Build
  • I created a C:\Wpo\Wpo.cpp file containing int main(){return 0;}
  • I created a C:\Wpo\CMakeLists.txt file containing the following:

    CMAKE_MINIMUM_REQUIRED (VERSION 3.10)
    PROJECT(Wpo)
    ADD_EXECUTABLE(Wpo "../Wpo.cpp")
    TARGET_COMPILE_OPTIONS(Wpo PRIVATE "$<$<CONFIG:Release>:/GL>")
    SET_TARGET_PROPERTIES(Wpo PROPERTIES LINK_FLAGS_RELEASE "/LTCG")
    
  • I openned a command line and created my Visual Studio solution:

    cd C:\Wpo\Build
    cmake ..
    

But when I open my solution in Visual Studio, Whole program Optimization is not set. Interestingly enough, there is a WholeProgramOptimization in the vcxproj file:

      <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
        <ClCompile>
          <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
          <AssemblerListingLocation>Release/</AssemblerListingLocation>
          <CompileAs>CompileAsCpp</CompileAs>
          <ExceptionHandling>Sync</ExceptionHandling>
          <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
          <Optimization>MaxSpeed</Optimization>
          <PrecompiledHeader>NotUsing</PrecompiledHeader>
          <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
          <RuntimeTypeInfo>true</RuntimeTypeInfo>
          <WarningLevel>Level3</WarningLevel>

          <WholeProgramOptimization>true</WholeProgramOptimization>

          <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
          <ObjectFileName>$(IntDir)</ObjectFileName>
          <DebugInformationFormat></DebugInformationFormat>
        </ClCompile>
      </ItemDefinitionGroup>

If I manually select Whole Program Optimizations from the Properties of the Project, an entry is added in another part of the vcxproj file:

      <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
        <ConfigurationType>Application</ConfigurationType>
        <CharacterSet>MultiByte</CharacterSet>
        <PlatformToolset>v141</PlatformToolset>

        <WholeProgramOptimization>true</WholeProgramOptimization>

      </PropertyGroup>
  • Is it a bug from CMake ? It looks like it is adding this WholeProgramOptimization section in the wrong place.
  • Is it a bug from Visual Studio ? It could be a regression too.
  • Am I employing a deprecated way of doing this ? This happens a lot with CMake ;-)

Any help would be greatly appreciated.

like image 707
Arnaud Avatar asked Jan 24 '18 21:01

Arnaud


2 Answers

There are 3 places in a Visual Studio project where Whole Program Optimization settings come into picture -

1) At Project level (Project → General tab)

WholeProgramOptimization

This is a convenience meta-setting to enable Whole Program Optimization.

In the project XML it's located at<PropertyGroup>/<WholeProgramOptimization>

2) At compiler level (C/C++ → Optimization tab)

WholeProgramOptimization /GL

This is the actual /GL setting, it defaults to the project-level setting.

In the project XML it's located at<ItemDefinitionGroup>/<ClCompile>/<WholeProgramOptimization>

3) At linker level (Linker → Optimization tab)

Link-Time Code Generation /LTGC

This is the actual /LTCG setting, it defaults to the project-level setting.

In the project XML it's located at <ItemDefinitionGroup>/<Link>/<LinkTimeCodeGeneration>

The following CMake commands won't set WholeProgramOptimization at project level, but at compiler and linker level. That's why the "convenience" setting in the General tab is blank. The net effect, however, is the same. WholeProgramOptimization is on.

set_target_properties(Wpo PROPERTIES COMPILE_FLAGS "$<$<CONFIG:Release>:/GL>")
set_target_properties(Wpo PROPERTIES LINK_FLAGS "$<$<CONFIG:Release>:/LTCG>")
like image 133
rustyx Avatar answered Nov 18 '22 04:11

rustyx


To use this feature you need to add compiler option /GL(whole program optimization) and linker option /LTCG (Link-time Code Generation).

SET_TARGET_PROPERTIES(Wpo PROPERTIES COMPILE_FLAGS "/GL")
SET_TARGET_PROPERTIES(Wpo PROPERTIES LINK_FLAGS "/LTCG")
like image 36
Ation Avatar answered Nov 18 '22 02:11

Ation