Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Register
  • Sign in
  • CMake CMake
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 4,165
    • Issues 4,165
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 13
    • Merge requests 13
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Releases
  • Packages and registries
    • Packages and registries
    • Container Registry
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • External wiki
    • External wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • CMakeCMake
  • CMakeCMake
  • Issues
  • #23980
Closed
Open
Issue created Sep 20, 2022 by tsondergaard@tsondergaard

IPO+PIE: Inconsistency between compilation and linking

Inconsistent use of -fPIE and -fPIC in compile and linker arguments leads to code generation error with INTERPROCEDURAL_OPTIMIZATION enabled.

Using CMake 3.22.2, gcc 12.2.1, and Qt 5.15.6 on Fedora 36 the following options:

include(CheckPIESupported)
check_pie_supported()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)

...triggers the following code to be compiled and linked incorrectly:

#include <iostream>
#include <QCoreApplication>
#include <QString>

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
    {
        auto foo = qEnvironmentVariable("an_env_var_that_is_not_set");
        std::cout << "1: isNull(): " << foo.isNull() << "\n";
    }

    {
        auto foo = qEnvironmentVariable("an_env_var_that_is_not_set", QString());
        std::cout << "2: isNull(): " << foo.isNull() << "\n";
    }
}

When compiled correctly the output of this program will be:

1: isNull(): 1
2: isNull(): 1

With the flags above the output is instead:

1: isNull(): 0
2: isNull(): 1

The full repro case can be found in example.zip

I have also reproduced the issue with CMake 3.20.2, gcc/g++ 11.2.1, and Qt 5.15.6 on RHEL 9.

With the flags above the compile and link steps executed are these:

[1/2] /usr/bin/c++ -DQT_CORE_LIB -DQT_NO_DEBUG -isystem /home/ts/src/qtbase-build/install/include -isystem /home/ts/src/qtbase-build/install/include/QtCore -isystem /home/ts/src/qtbase-build/install/./mkspecs/linux-g++ -O2 -g -DNDEBUG -flto -fno-fat-lto-objects -fPIE -fPIC -MD -MT CMakeFiles/example.dir/example.cc.o -MF CMakeFiles/example.dir/example.cc.o.d -o CMakeFiles/example.dir/example.cc.o -c /home/ts/src/easyviz-3/example/example.cc
[2/2] : && /usr/bin/c++ -O2 -g -DNDEBUG -flto -fno-fat-lto-objects -fPIE -pie CMakeFiles/example.dir/example.cc.o -o example  -Wl,-rpath,/home/ts/src/qtbase-build/install/lib  /home/ts/src/qtbase-build/install/lib/libQt5Core.so.5.15.6 && :

Notice that the compile step passes -fPIE -fPIC, whereas the link step only passes -fPIE. If I manually amend the link step to pass -fPIE -fPIC it solves the problem. Note here that the order matters - passing -fPIE -fPIC fixes the problem, but -fPIC -fPIE does not.

This issue does not reproduce with the distro-provided versions of Qt, and I have no idea why. The attached example.zip contains full instructions for also building Qt 5.15.6 - on a reasonably modern computer the whole repro case can be executed in 5-10 minutes of setup and build time.

I am opening a bug here, rather than with Qt or gcc, because I think it is a bug that CMake doesn't pass consistent flags to the compiler and the linker when INTERPROCEDURAL_OPTIMIZATION is enabled.

Edited Sep 20, 2022 by Brad King
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking