Currently to change a compiler flag when using gcc, I edit the CMakeLists.txt for the build target:
if (UNIX)
add_definitions(-Wall)
add_definitions(-g)
#add_definitions(-O2)
endif (UNIX)
The problem with this is that git picks up the change. If I go ahead and commit this change, I will annoy the other developers who expect to use -O2 instead of -g but they get my version when they pull unrelated changes. Normally, I could just exclude this change from my commits, but when I make an actual change to the CMakeLists.txt file, there is no way to avoid pushing up my personal selection of compile flags.
Is there a way to tell CMake to create a file in the build/ directory (specific to each working copy, and therefore to each developer) that an individual person can modify to their heart's desire without touching project files (everything but build/). Naturally, our build/ is not committed to the git repository.
It might be helpful to note that when using Visual Studio instead of gcc, the IDE handles this for us through its UI which modifies the VS solution file in build/. The problem is that we have no such mechanism when using GNU Makefiles.
Our project is organized like this:
ourproject/
bin/
build/ <-- CMake-generated stuff goes here
lib/
src/
abuildtarget/
anotherbuildtarget/
source.cpp
source.h
CMakeLists.txt
You are using CMake incorrectly here. The add_definitions
function is not for adding compiler options like you are doing; rather, it is to add pre-processor definitions such as add_definitions(-DDEBUG)
.
What you want to do is set the CMAKE_<language>_FLAGS
when you configure to the options you want. If there is a standard set you need, then put that in the CMakeLists.txt file such as:
if(${CMAKE_Fortran_COMPILER_ID} STREQUAL "Intel")
set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -xhost" CACHE STRING "" FORCE)
set(CMAKE_Fortran_FLAGS_NODEBUG "-O0" CACHE STRING "" FORCE)
mark_as_advanced(CMAKE_Fortran_FLAGS_NODEBUG)
set(CMAKE_Fortran_FLAGS_PROFILING "-O2 -xhost -p" CACHE STRING "" FORCE)
mark_as_advanced(CMAKE_Fortran_FLAGS_PROFILING)
set(CMAKE_Fortran_FLAGS_DEBUG
"-DDEBUG -g -check noarg_temp_created -C -traceback" CACHE STRING "" FORCE)
endif()
Where Fortran
can be replaced by CXX
or C
.
In this case, the CMAKE_<language>_FLAGS_<build type>
sets the flags based on the CMAKE_BUILD_TYPE
variable. If it is set to Release
, then it uses CMAKE_Fortran_FLAGS_RELEASE
. We added several other possible build types. If the user wants something that isn't one of the standard build types, then they set CMAKE_<language>_FLAGS
to whatever they want when configuring and it overrides the build type setting and uses the user-defined flags instead.
While there's almost certainly a better method of utilising cmake
to solve your problem, this part of your question is easily addressed:
but when I make an actual change to the CMakeLists.txt file, there is no way to avoid pushing up my personal selection of compile flags.
This is only true if you commit your specific, personal file changes to your local repository, and even then you can either git-revert
when you make a patch to push, or use a filter between your development
and ready-to-push-to-other-developers
branches - the rough idea can be found here, although you'll have to edit it pretty heavily to remove the offending personal lines from the questions example.
A better option, then, is to not commit the personal changes. From the answer here, you can easily commit specific changes to a file.
A thing to note, however, is that you'll end up with a permanently dirty work-tree if you've got uncommitted changes to a non-ignored file; this may or may not be an issue, depending on your workflow for merges etc.