jpfx1342
jpfx1342

Reputation: 908

Any way to set CMake variables for all projects?

I've been building a lot of projects with CMake recently, and overall, I think it's great. However, anytime I need to build a project with dependencies, it quickly becomes a pain.

System installed dependencies are fine, because CMake's find_package system is usually pretty good about finding system installed packages. However, any time I build a dependency from source, I find that it's almost impossible to tell CMake where to find the packages.

I keep ending up searching through the FindFoo.cmake module, figuring out what special hint variable it's looking at, then setting that variable to where my library is. The real problem is that because these hint variables are always CMake variables, I end up having to either set them in my own CMakeLists.txt, which is really dirty, or wrapping cmake in a script file to make sure it's passed all the proper hint variables it needs to find packages.

I would just set environment variables, but most of the FindFoo.cmake modules don't actually check any environment variables.

I looked into using the Package Registry to help solve my problem, but if CMake finds a FindFoo.cmake module, it doesn't even bother looking in the registry, and CMake just gives up when the FindFoo.cmake module fails.

What I'm looking for is some way to set variables at "user scope" or "system scope" in CMake, so I can just specify my hint variables in one place instead of across a bunch of project and script files. Unfortunately, I don't seem to be able to find any such functionality.

I'm on Windows, but I'm looking for as general of a solution as possible, because I may not be in the future.

Upvotes: 3

Views: 3280

Answers (2)

jpfx1342
jpfx1342

Reputation: 908

@wasthehelpful's answer mentions creating a my-paths.cmake file, then importing that into my projects. This is almost a perfect solution, except that it still requires modifying the project. However, after reading the cmake manual some more, I've realized that it has an option to pre-load an "initial-cache" .cmake file.

So I've created a local.cmake file in an easily accessible location, filled with entries like this:

set(ZLIB_ROOT "`~/builds/zlib-1.2.8" CACHE PATH "")
set(PNG_ROOT "~/builds/libpng-1.6.27" CACHE PATH "")
set(OSG_DIR "~/builds/OpenSceneGraph_3.4.0" CACHE PATH "")

Then, to configure my project, I invoke cmake like this:

cmake -C "~/local.cmake" ..

This solution still requires specifying a command line argument, but it's a single argument, and should be easy to remember.

(I'm going to leave this question unanswered for a bit, in case someone comes up with a better solution.)

Upvotes: 0

rocambille
rocambille

Reputation: 15976

This is achieved through cmake-gui: you set the paths and it will remain in the cache of your project unless the cache is deleted.

If you are using CMake in command line, you can give the paths as arguments:

cmake -DCMAKE_PREFIX_PATH=/some/path -DFOO_ROOT=/some/path/to/foo

An other option would be to set the paths in a separate file to be included in your CMakeLists.txt. You may check if the file exists and generate some template file with a warning message if it isn't available. Something like this:

set(MY_CMAKE_PATHS "${PROJECT_BINARY_DIR}/my-cmake.paths")

if(EXISTS "${MY_CMAKE_PATHS}")
    include("${MY_CMAKE_PATHS}")
else()
    file(COPY "${PROJECT_SOURCE_DIR}/my-cmake.paths" DESTINATION "${PROJECT_SOURCE_DIR}"
    message(FATAL_ERROR
        "CMake paths are not available. "
        "Please edit the file \"${MY_CMAKE_PATHS}\" with the appropriate values."
    )
endif()

With ${PROJECT_SOURCE_DIR}/my-cmake.paths being something like that:

set(CMAKE_PREFIX_PATH ) # some comment to explain what is expected here
set(FOO_ROOT )          # some comment...

It is up to you to maintain the file with all the variables you want to be filled, and with the appropriate comments to help user to use it.

The paths file is here copied in PROJECT_BINARY_DIR, but you may as well copy and use it in a "common" path for all your projects.

Upvotes: 1

Related Questions