特定于本地工作副本的CMake编译器设置

特定于本地工作副本的CMake编译器设置,cmake,Cmake,当前,为了在使用gcc时更改编译器标志,我编辑了构建目标的CMakeLists.txt: if (UNIX) add_definitions(-Wall) add_definitions(-g) #add_definitions(-O2) endif (UNIX) 问题是git接受了更改。如果我继续进行并提交此更改,我会惹恼其他希望使用-O2而不是-g的开发人员,但他们在进行不相关的更改时得到了我的版本。通常,我可以从提交中排除此更改,但当我对CMakeLists.tx

当前,为了在使用gcc时更改编译器标志,我编辑了构建目标的CMakeLists.txt:

if (UNIX)
    add_definitions(-Wall)
    add_definitions(-g)
    #add_definitions(-O2)
endif (UNIX)
问题是git接受了更改。如果我继续进行并提交此更改,我会惹恼其他希望使用-O2而不是-g的开发人员,但他们在进行不相关的更改时得到了我的版本。通常,我可以从提交中排除此更改,但当我对CMakeLists.txt文件进行实际更改时,无法避免推高我个人选择的编译标志

是否有一种方法可以告诉CMake在build/目录中创建一个文件(特定于每个工作副本,因此也适用于每个开发人员),个人可以根据自己的意愿修改该文件,而无需触及项目文件(除了build/)。当然,我们的build/build没有提交到git存储库

请注意,当使用VisualStudio而不是gcc时,IDE通过其UI为我们处理此问题,该UI修改build/中的VS解决方案文件。问题是我们在使用GNU Makefiles时没有这样的机制

我们的项目是这样组织的:

ourproject/
    bin/
    build/ <-- CMake-generated stuff goes here
    lib/
    src/
        abuildtarget/
        anotherbuildtarget/
            source.cpp
            source.h
            CMakeLists.txt
我们的项目/
垃圾箱/

build/您在此处错误地使用了CMake。
add_definitions
函数不像您现在这样用于添加编译器选项;而是添加预处理器定义,例如
add\u definitions(-DDEBUG)

您要做的是在配置所需选项时设置
CMAKE\u标志。如果您需要标准集,请将其放入CMakeLists.txt文件中,例如:

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()
其中,
Fortran
可替换为
CXX
C


在这种情况下,
CMAKE\u FLAGS\u
基于
CMAKE\u BUILD\u TYPE
变量设置标志。如果设置为
Release
,则使用
CMAKE\u Fortran\u FLAGS\u Release
。我们添加了其他几种可能的构建类型。如果用户想要的不是标准生成类型之一的内容,则在配置时,他们会将
CMAKE\u标志设置为他们想要的任何内容,并且它会覆盖生成类型设置并使用用户定义的标志。

您在此处使用的CMAKE不正确。
add_definitions
函数不像您现在这样用于添加编译器选项;而是添加预处理器定义,例如
add\u definitions(-DDEBUG)

您要做的是在配置所需选项时设置
CMAKE\u标志。如果您需要标准集,请将其放入CMakeLists.txt文件中,例如:

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()
其中,
Fortran
可替换为
CXX
C


在这种情况下,
CMAKE\u FLAGS\u
基于
CMAKE\u BUILD\u TYPE
变量设置标志。如果设置为
Release
,则使用
CMAKE\u Fortran\u FLAGS\u Release
。我们添加了其他几种可能的构建类型。如果用户想要的不是标准构建类型之一,那么他们在配置时会将
CMAKE\uu标志设置为他们想要的任何内容,它会覆盖构建类型设置,并使用用户定义的标志来代替。

虽然几乎可以肯定有更好的方法利用
CMAKE
来解决您的问题,这部分问题很容易回答:

但是,当我对CMakeLists.txt文件进行实际更改时,无法避免推高我个人选择的编译标志

只有当您将特定的个人文件更改提交到本地存储库时,这才是正确的,即使这样,您也可以在制作要推送的修补程序时进行
git revert
,或者在
开发
准备推送给其他开发人员的分支之间使用过滤器-可以找到大致的想法,尽管您必须对其进行大量编辑,以从问题示例中删除令人不快的个人行

因此,更好的选择是不提交个人更改。根据答案,您可以轻松地将特定更改提交到文件


然而,需要注意的是,如果您对一个未被忽略的文件进行了未提交的更改,那么最终将得到一个永久的脏工作树;这可能是问题,也可能不是问题,取决于您的合并等工作流程。

虽然几乎可以肯定有更好的方法利用
cmake
解决您的问题,但这部分问题很容易解决:

但是,当我对CMakeLists.txt文件进行实际更改时,无法避免推高我个人选择的编译标志

只有当您将特定的个人文件更改提交到本地存储库时,这才是正确的,即使这样,您也可以在制作要推送的修补程序时进行
git revert
,或者在
开发
准备推送给其他开发人员的分支之间使用过滤器-可以找到大致的想法,尽管您必须对其进行大量编辑,以从问题示例中删除令人不快的个人行

因此,更好的选择是不提交个人更改。根据答案,您可以轻松地将特定更改提交到文件


然而,需要注意的是,如果您对一个未被忽略的文件进行了未提交的更改,那么最终将得到一个永久的脏工作树;这可能是一个问题,也可能不是,这取决于您的合并等工作流。

我认为您不应该只设置标志-它将覆盖以前放在那里的内容(例如,用户在命令行上指定
-DCMAKE\u Fortran\u flags=…
)。我宁愿做
set(CMAKE\u Fortran\u FLAGS“${CMAKE\u Fortran\u FLAGS}new\u stuff”)
@Ela782我认为最好的做法是像我在示例中那样设置
CMAKE\u Fortran\u FLAGS\u
标志,因为这些标志应该由代码而不是用户设置。用户始终可以覆盖其中任何一个