Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A bunch of CMake fixes #1178

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

A bunch of CMake fixes #1178

wants to merge 5 commits into from

Conversation

graebm
Copy link
Contributor

@graebm graebm commented Dec 19, 2024

Issue #:

Description of changes:

  • Indicate that project is known to work with latest CMake
    • OLD: cmake_minimum_required(VERSION 3.9)
    • NEW: cmake_minimum_required(VERSION 3.9...3.31)
    • REASONING: This gets the CMake 3.10 deprecation warnings to go away. Months ago I realized this fixed the warnings, but hesitated to add it since the "...<max>" syntax wasn't introduced until CMake 3.12. But in the docs they call out that it's safe to use even in older projects

      If the running version of CMake is older than 3.12, the extra ... dots will be seen as version component separators, resulting in the ...<max> part being ignored and preserving the pre-3.12 behavior of basing policies on <min>.

  • Respect CMAKE_INSTALL_LIBDIR, CMAKE_INSTALL_BINDIR, CMAKE_INSTALL_INCLUDEDIR
    • Use these variables directly, instead of defining our own (LIBRARY_DIRECTORY, RUNTIME_DIRECTORY)
    • include(GNUInstallDirs) on all platforms
    • REASONING: This removes a bunch of boilerplate, and makes it obvious we should defer to CMake for install directory names. I assume the original author thought GNUInstallDirs wasn't safe for Windows and Apple, but despite its name, it's fine. Professional CMake says:

      CMake’s GNUInstallDirs module provides a very convenient way to use a standard directory layout. ... it also provides various other standard locations that conform to both GNU coding standards and the FHS. ... the layout can even be used for Windows deployments

  • Move installed aws-c-common-config.cmake
    • OLD: lib/aws-c-common/cmake/...
    • NEW: lib/cmake/aws-c-common/...
    • REASONING: while both the old and new locations will work with find_package(), the new location is more standard.
  • Move installed CMake modules like AwsCFlags.cmake
    • OLD: lib/cmake/...
    • NEW: lib/cmake/aws-c-common/modules/...
    • REASONING: it's standard to put ALL of a library's scripts under the same folder. It also makes the location easier to find in the next step...
  • Tweak aws-c-common-config.cmake so that, when any dependency calls find_package(aws-c-common), the CMAKE_MODULE_PATH is modified to include the installed location of modules like AwsCFlags.cmake.
    • REASONING: aws-c-common has a bunch of CMake modules (e.g. AwsCFlags.cmake) that are used in downstream dependencies (e.g. aws-checksums). The way that aws-c-common installs these modules, and the way that dependencies consume them, is non-standard. This leads to a lot of hacky boilerplate in each dependency (example: aws-checksums/CMakeListst.txt, and has caused headaches for various distributions that try and package these dependencies.
  • Stop manually setting FIND_LIBRARY_USE_LIB64_PATHS, just let CMake handle it
    • REASONING: Here's what Professional CMake: A Practical Guide 12th Edition has to say on this topic:

      CMake is generally aware of the variations and when setting up the platform defaults, it populates the global properties FIND_LIBRARY_USE_LIB32_PATHS, FIND_LIBRARY_USE_LIB64_PATHS and FIND_LIBRARY_USE_LIBX32_PATHS with appropriate values to control which architecture-specific directories should be searched first, if any. Projects can override these with their own custom prefix using the CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX variable, but the need for this should be very rare.

      This wasn't causing issues, but I'm trying to cut down on the hacky boilerplate copy/pasted into dozens of other CMake files amongst our repos. In the PR that introduced this, it's commented with "this is the absolute dumbest thing in the world" and a reviewer mentions that it's not necessary in aws-sdk-cpp. My best guess as to why it seemed necessary is that we were trying to get cross-compile working somewhere and this fixed it. But it seems like the real fix is to address this in the cross-compilation toolchain file. It shouldn't be up to every CMake library on earth to include this hack. Removing now in 2024 doesn't seem to cause any issues, so 🪓

Thanks to @r-burns @madebr @glaubitz and others for helpful comments, and the Pull Requests it took us years to finally look at

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

This eliminates a CMake Deprecation Warning.
The comment says we added this to "Enable options to get their values from normal variables"
But reading the docs: https://cmake.org/cmake/help/latest/policy/CMP0077.html
it seems like the NEW behavior is what lets options get their values from normal variables
…es like LIBRARY_DIRECTORY. Since every platform can do `include(GnuInstallDirs)`, it's fine to rely on the variables it defines, so let's just use them explicitly.

- Explicitly include(GNUInstallDirs) in every CMakeLists.txt that uses the vars it defines (e.g. CMAKE_INSTALL_LIBDIR). I could get away omitting this include, since the AwsSharedLibsSetup.cmake helper script also pulls it in, but it seems like good practice.
- Remove custom code that was setting FIND_LIBRARY_USE_LIB64_PATHS. In the PR that introduced this #226 the reviewer called out that this probably wasn't necessary. ChatGPT agrees. CMake is supposed to figure this out automatically. And if it's not working, then it's a weird cross-compile situation where the person building should be setting this to fix things. It shouldn't be up to every library on earth to do this hack.

So, this PR started with me thinking that, if we're getting all the shared scripts via `find_package(aws-c-common)`, and the shared scripts are where FIND_LIBRARY_USE_LIB64_PATHS gets customized, but we need to customize FIND_LIBRARY_USE_LIB64_PATHS before we can do `find_package(aws-c-common)`, then ALL projects need to copy/paste the code that customizes FIND_LIBRARY_USE_LIB64_PATHS before doing `find_package(aws-c-common)`. So I set down that path. Then when writing the commit message I was like  ... wait a minute this is ridiculous. So did some more research, and learned the FIND_LIBRARY_USE_LIB64_PATHS stuff was probably unnecessary.
@graebm graebm changed the title Install CMake modules in a more standard way. A bunch of CMake fixes Dec 23, 2024
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.

3 participants