How can I tell CMake to put include directory flags after the compiler option flags in its object compile command?

huangapple go评论58阅读模式
英文:

How can I tell CMake to put include directory flags after the compiler option flags in its object compile command?

问题

I am facing problems due to the target holding the include paths first and then the compiler options after. How can I set the include paths after the compiler options for compiling source files of a target?

我的问题是,目标首先保存包含路径,然后是编译选项。如何为目标的源文件设置编译选项后设置包含路径?

My CMakeLists.txt file:

我的CMakeLists.txt文件:

project(HelloWorld)
cmake_minimum_required(VERSION 3.0)
add_library(HELLO_WORLD_LIB STATIC src/helloWorld.cpp)
target_include_directories(HELLO_WORLD_LIB AFTER PUBLIC D:\temp\includes)
target_compile_options(HELLO_WORLD_LIB BEFORE PUBLIC -cpp -remap)
set_target_properties(HELLO_WORLD_LIB
PROPERTIES
OUTPUT_NAME hello
ARCHIVE_OUTPUT_DIRECTORY D:\temp\CMakeHelloWorld
SUFFIX .a
)

My cmake call:

我的cmake调用:

call cmake -GNinja -S ./.. -DCMAKE_INSTALL_PREFIX=../_bin
call cmake --build . --config Debug --verbose -d keeprsp
call cmake --install .

The console output:

控制台输出:

-- Configuring done
-- Generating done
-- Build files have been written to: D:/temp/CMakeHelloWorld/_build
[1/2] C:\mingw\test25_comp_8.1.0_testversion\bin\c++.exe -ID:/temp/includes -cpp -remap -MD -MT CMakeFiles/HELLO_WORLD_LIB.dir/src/helloWorld.cpp.obj -MF CMakeFiles\HELLO_WORLD_LIB.dir\src\helloWorld.cpp.obj.d -o CMakeFiles/HELLO_WORLD_LIB.dir/src/helloWorld.cpp.obj -c ../src/helloWorld.cpp
[2/2] cmd.exe /C "cd . && C:\cmake.8-3.20.2\bin\cmake.exe -E rm -f ..\libhello.a && C:\mingw\test25_comp_8.1.0_testversion\bin\ar.exe qc ..\libhello.a CMakeFiles/HELLO_WORLD_LIB.dir/src/helloWorld.cpp.obj && C:\mingw\test25_comp_8.1.0_testversion\bin\ranlib.exe ..\libhello.a && cd ."
-- Install configuration: ""

However if I try to add the include paths after compiler options, it sits before the compiler options. How can I set the compiler options before the include directories? like C:\mingw\test25_comp_8.1.0_testversion\bin\c++.exe -cpp -remap -ID:/temp/includes.

然而,如果我尝试在编译选项之后添加包含路径,它会位于编译选项之前。如何在包含目录之前设置编译选项,就像C:\mingw\test25_comp_8.1.0_testversion\bin\c++.exe -cpp -remap -ID:/temp/includes

英文:

I am facing problems due to the target holding the include paths first and then the compiler options after. How can I set the include paths after the compiler options for compiling source files of a target?

My CMakeLists.txt file:

project(HelloWorld)
cmake_minimum_required(VERSION 3.0)
add_library(HELLO_WORLD_LIB
                STATIC
                src/helloWorld.cpp
    )
target_include_directories(
            HELLO_WORLD_LIB AFTER PUBLIC D:\\temp\\includes 
        )
target_compile_options(HELLO_WORLD_LIB BEFORE PUBLIC -cpp -remap)
set_target_properties(HELLO_WORLD_LIB
        PROPERTIES
            OUTPUT_NAME hello
            ARCHIVE_OUTPUT_DIRECTORY  D:\\temp\\CMakeHelloWorld
            SUFFIX .a
    )

My cmake call:

call cmake -GNinja -S ./.. -DCMAKE_INSTALL_PREFIX=../_bin
call cmake --build . --config Debug --verbose -d keeprsp
call cmake --install .

The console output:

-- Configuring done
-- Generating done
-- Build files have been written to: D:/temp/CMakeHelloWorld/_build
[1/2] C:\mingw\test25_comp_8.1.0_testversion\bin\c++.exe -ID:/temp/includes -cpp -remap -MD -MT CMakeFiles/HELLO_WORLD_LIB.dir/src/helloWorld.cpp.obj -MF CMakeFiles\HELLO_WORLD_LIB.dir\src\helloWorld.cpp.obj.d -o CMakeFiles/HELLO_WORLD_LIB.dir/src/helloWorld.cpp.obj -c ../src/helloWorld.cpp
[2/2] cmd.exe /C "cd . && C:\cmake\.8-3.20.2\bin\cmake.exe -E rm -f ..\libhello.a && C:\mingw\test25_comp_8.1.0_testversion\bin\ar.exe qc ..\libhello.a  CMakeFiles/HELLO_WORLD_LIB.dir/src/helloWorld.cpp.obj && C:\mingw\test25_comp_8.1.0_testversion\bin\ranlib.exe ..\libhello.a && cd ."
-- Install configuration: ""

However if I try to add the include paths after compiler options, it sits before the compiler options. How can I set the compiler options before the include directories? like C:\mingw\test25_comp_8.1.0_testversion\bin\c++.exe -cpp -remap -ID:/temp/includes.

答案1

得分: 2

The relevant CMake variable is CMAKE_CXX_COMPILE_OBJECT, which is the configuration point for what template to use for the command to compile an object. The default value is set in Modules/CMakeCXXInformation.cmake, and overrides are specified in various Modules/Platform/* or Modules/Compiler/* files. If you're curious, you can grep for the overrides with the following regex: set.*CXX_COMPILE_OBJECT.

The default one is set like this:

set(CMAKE_CXX_COMPILE_OBJECT
  "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")

You probably want something like this (set it in your own CMakeLists.txt file, or in a toolchain file):

set(CMAKE_CXX_COMPILE_OBJECT
  "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> <INCLUDES> -o <OBJECT> -c <SOURCE>")

As far as I can tell, this configuration point is "global". I'm not aware of how to specify it with different values for different targets or source files.


If you're working with the Ninja generator and need this kind of change to affect the generated .rsp files, I think you'd need to build a modified version of CMake from source, since that behavior seems to be baked into the binaries instead of CMake script files in the Modules/ directory. The relevant source file is Source/cmNinjaTargetGenerator.cxx. Look at the lines of code that do rule.RspContent = and you'll see:

rule.RspContent =
  cmStrCat(' ', scanVars.Defines, ' ', scanVars.Includes, ' ', scanFlags);

You'd probably need to switch the order of scanVars.Includes and scanVars.scanFlags.

If you choose to make a modified CMake binary, as always, make sure you comply with the software license.

英文:

The relevant CMake variable is CMAKE_CXX_COMPILE_OBJECT, which is the configuration point for what template to use for the command to compile an object. The default value is set in Modules/CMakeCXXInformation.cmake, and overrides are specified in various Modules/Platform/* or Modules/Compiler/* files. If you're curious, you can grep for the overrides with the following regex: set.*CXX_COMPILE_OBJECT.

The default one is set like this:

set(CMAKE_CXX_COMPILE_OBJECT
  &quot;&lt;CMAKE_CXX_COMPILER&gt; &lt;DEFINES&gt; &lt;INCLUDES&gt; &lt;FLAGS&gt; -o &lt;OBJECT&gt; -c &lt;SOURCE&gt;&quot;)

You probably want something like this (set it in your own CMakeLists.txt file, or in a toolchain file):

set(CMAKE_CXX_COMPILE_OBJECT
  &quot;&lt;CMAKE_CXX_COMPILER&gt; &lt;DEFINES&gt; &lt;FLAGS&gt; &lt;INCLUDES&gt; -o &lt;OBJECT&gt; -c &lt;SOURCE&gt;&quot;)

As far as I can tell, this configuration point is "global". I'm not aware of how to specify it with different values for different targets or source files.


If you're working with the Ninja generator and need this kind of change to affect the generated .rsp files, I think you'd need to build a modified version of CMake from source, since that behaviour seems to be baked into the binaries instead of CMake script files in the Modules/ directory. The relecant source file is Source/cmNinjaTargetGenerator.cxx. Look at the lines of code that do rule.RspContent = and you'll see:

rule.RspContent =
  cmStrCat(&#39; &#39;, scanVars.Defines, &#39; &#39;, scanVars.Includes, &#39; &#39;, scanFlags);

You'd probably need to switch the order of scanVars.Includes and scanVars.scanFlags.

If you choose to make a modified CMake binary, as always, make sure you comply with the software licence.

huangapple
  • 本文由 发表于 2023年2月18日 11:25:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75490990.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定