Search code examples
cmake

CMake how to set the build directory to be different than source directory


I'm pretty new to CMake, and read a few tutorials on how to use it, and wrote some complicated 50 lines of CMake script in order to make a program for 3 different compilers. This probably concludes all my knowledge in CMake.

Now my problem is that I have some source code, whose folder I don't want to touch/mess with when I make the program. I want that all CMake and make output files and folders to go into ../Compile/, so I changed a few variables in my CMake script for that, and it worked for sometime when I did something like this on my laptop:

Compile$ cmake ../src
Compile$ make

Where with that I had a clean output in the folder I'm in right now, which is exactly what I'm looking for.

Now I moved to another computer, and recompiled CMake 2.8.11.2, and I'm almost back to square one! It always compiles the thing into the src folder where my CMakeLists.txt is located.

The part where I choose the directory in my CMake script is this:

set(dir ${CMAKE_CURRENT_SOURCE_DIR}/../Compile/)
set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(LIBRARY_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dir})
set(CMAKE_BUILD_FILES_DIRECTORY ${dir})
set(CMAKE_BUILD_DIRECTORY ${dir})
set(CMAKE_BINARY_DIR  ${dir})
SET(EXECUTABLE_OUTPUT_PATH ${dir})
SET(LIBRARY_OUTPUT_PATH ${dir}lib)
SET(CMAKE_CACHEFILE_DIR ${dir})

And now it always ends with:

-- Build files have been written to: /.../src

Am I missing something?


Solution

  • There's little need to set all the variables you're setting. CMake sets them to reasonable defaults. You should definitely not modify CMAKE_BINARY_DIR or CMAKE_CACHEFILE_DIR. Treat these as read-only.

    First remove the existing problematic cache file from the src directory:

    cd src
    rm CMakeCache.txt
    cd ..
    

    Then remove all the set() commands and do:

    cd Compile && rm -rf *
    cmake ../src
    

    As long as you're outside of the source directory when running CMake, it will not modify the source directory unless your CMakeList explicitly tells it to do so.

    Once you have this working, you can look at where CMake puts things by default, and only if you're not satisfied with the default locations (such as the default value of EXECUTABLE_OUTPUT_PATH), modify only those you need. And try to express them relative to CMAKE_BINARY_DIR, CMAKE_CURRENT_BINARY_DIR, PROJECT_BINARY_DIR etc.

    If you look at CMake documentation, you'll see variables partitioned into semantic sections. Except for very special circumstances, you should treat all those listed under "Variables that Provide Information" as read-only inside CMakeLists.