Skip to content

Conversation

@ricab
Copy link
Collaborator

@ricab ricab commented Apr 10, 2025

CMake can't use mold with GCC versions below 12.1, so skip it.

CMake can't use mold with GCC versions below 12.1, so skip it.
CMakeLists.txt Outdated

project(Multipass)

include(src/cmake/environment-utils.cmake)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to move this so that we know what compiler was picked up. However, at this point the CMAKE_LINKER is also already set and I don't think it will get affected. I could set it manually, but I wonder if that's the right thing to do...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well not this line, the whole block...

@codecov
Copy link

codecov bot commented Apr 10, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 89.53%. Comparing base (6167951) to head (e106b64).
Report is 3416 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4036      +/-   ##
==========================================
+ Coverage   89.37%   89.53%   +0.15%     
==========================================
  Files         260      260              
  Lines       14734    14741       +7     
==========================================
+ Hits        13169    13198      +29     
+ Misses       1565     1543      -22     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ricab
Copy link
Collaborator Author

ricab commented Apr 10, 2025

Nah I don't think this would work. The compiler and linker are selected around the same time, so it's not easy to select one depending on the other. I can't be bothered at this point...

@ricab
Copy link
Collaborator Author

ricab commented Apr 10, 2025

Actually, it kinda seems to be working. I see -fuse-ld=lld being passed to the compiler and:

$ readelf -p .comment dhcp_release

String dump of section '.comment':
  [     1]  GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
  [    2c]  Linker: Ubuntu LLD 16.0.6

@xmkg what are your thoughts on this?

@xmkg
Copy link
Member

xmkg commented Apr 10, 2025

Actually, it kinda seems to be working. I see -fuse-ld=lld being passed to the compiler and:

$ readelf -p .comment dhcp_release

String dump of section '.comment':
  [     1]  GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
  [    2c]  Linker: Ubuntu LLD 16.0.6

@xmkg what are your thoughts on this?

I'm currently looking into a viable strategy to tackle this. The CMAKE_LINKER_TYPE has to be set before the project() call because the project() call will trigger a bunch of stuff, including some try_compile()'s which will use the linker. So, there's a check_language function which could help us identify which compiler is being used, but it does not define the version variable, so we have to read and parse the gcc output. There might be a CMake internal utility function that can help, but the idea needs exploring.

Right now I found this issue, which is exactly what we're dealing with right now. I haven't read through all of it, but it seems promising. I'll post my findings.

@xmkg
Copy link
Member

xmkg commented Apr 10, 2025

Actually, it kinda seems to be working. I see -fuse-ld=lld being passed to the compiler and:

$ readelf -p .comment dhcp_release

String dump of section '.comment':
  [     1]  GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
  [    2c]  Linker: Ubuntu LLD 16.0.6

@xmkg what are your thoughts on this?

I'm currently looking into a viable strategy to how to tackle this. The CMAKE_LINKER_TYPE has to be set before the project() call because the project() call will trigger a bunch of stuff, including some try_compile()'s which will use the linker. So, there's a check_language function which could help us identify which compiler is being used, but it does not define the version variable, so we have to read and parse the gcc output. There might be a CMake internal utility function that can help, but the idea needs exploring.

Right now I found this issue, which is exactly what we're dealing with right now. I haven't read through all of it, but it seems promising. I'll post my findings.

For reference., this is the PR that introduces the CMAKE_LINKER_TYPE feature: https://gitlab.kitware.com/cmake/cmake/-/merge_requests/8861/diffs#63ee1ac156219ea3f9cd7a3517886d40b04759ac

@ricab
Copy link
Collaborator Author

ricab commented Apr 10, 2025

OK yeah, if there is a better way to do this, let's go for that. check_language sounds like a promising way to get out of the chicken-and-egg problem.

I am going to have to leave this aside because it's already taken way too much of my time. So feel free to pick it up and thanks in advance if you do.

@xmkg
Copy link
Member

xmkg commented Apr 10, 2025

@ricab since the -B<linker-path> approach is the common thing between the old/new gcc versions, what do you think if we use something like this?:

function(configure_linker)
    if(${CMAKE_VERSION} VERSION_LESS "3.29")
        message(STATUS "configure_linker is only supported in CMake 3.29 and above.")
        return()
    endif()

    if(NOT DEFINED CMAKE_LINKER_TYPE)
        if (WIN32)
            set (LLD_LINKER_NAMES lld-link)
        else()
            set(LLD_LINKER_NAMES ld.lld ld64.lld)
            set(MOLD_LINKER_NAMES /usr/libexec/mold/ld /usr/local/libexec/mold/ld mold sold)
            find_program(MOLD_LINKER NAMES ${MOLD_LINKER_NAMES})
        endif()

        find_program(LLD_LINKER NAMES ${LLD_LINKER_NAMES})

        if(MOLD_LINKER)
            message(STATUS "configure_linker: `mold` (${MOLD_LINKER}) found in environment, will use it as default.")
            set(CMAKE_LINKER_TYPE MOLD PARENT_SCOPE)
            if(MOLD_LINKER MATCHES "libexec")
                string(REPLACE "/ld" "" MOLD_LINKER_PATH ${MOLD_LINKER})
                set(CMAKE_CXX_USING_LINKER_MOLD "-B${MOLD_LINKER_PATH}" PARENT_SCOPE)
            endif()
        elseif(LLD_LINKER)
            message(STATUS "configure_linker: `lld` found in environment, will use it as default.")
            set(CMAKE_LINKER_TYPE LLD PARENT_SCOPE)
        else()
            message(STATUS "configure_linker: neither `mold` or `lld` is present in the environment, will use the toolchain default.")
        endif()
    else()
        message(STATUS "configure_linker: will use the user specified linker: `${CMAKE_LINKER_TYPE}`")
    endif()
endfunction()

The < GCC 12.1 does not support "-fuse-ld=mold" so the code falls
back to adding the mold's `ld` symlink path to the compiler's search
path by `-B`.

Signed-off-by: Mustafa Kemal Gilor <mustafa.gilor@canonical.com>
@ricab
Copy link
Collaborator Author

ricab commented Apr 10, 2025

Yep, confirmed with GCC 11 and 13.

I can't review my own PR, so @xmkg you'll need to formally review yourself (or separate PR).

@ricab ricab requested a review from xmkg April 10, 2025 16:40
@xmkg xmkg marked this pull request as ready for review April 10, 2025 16:49
@xmkg xmkg added this pull request to the merge queue Apr 11, 2025
Merged via the queue into main with commit 896fcb7 Apr 11, 2025
23 checks passed
@xmkg xmkg deleted the prevent-mold-old-gcc branch April 11, 2025 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants