【问题标题】:CMake override native compiler flagsCMake 覆盖本机编译器标志
【发布时间】:2016-06-29 11:09:19
【问题描述】:

我正在尝试使用 Visual Studio 14 使用 CMake 构建一个 c 项目,但是我无法覆盖由 CMake 设置的编译器标志,这会导致项目无法构建。我在我的 CMakeLists.txt 文件中使用此方法

set(flags /nologo /c /EHsc /GS- /MTd /Od /TC /Zi /Zp2 /D _USING_V110_SDK71_)
set(CMAKE_C_FLAGS ${flags})
set(rc_flags /l0x809)
set(CMAKE_RC_FLAGS ${rc_flags})
set(linker_flags /NOLOGO /SUBSYSTEM:console /MACHINE:I386 /DLL)
set(CMAKE_LINKER_FLAGS ${linker_flags})

任何帮助将不胜感激!

编辑:主要 CMakeLists.txt 的完整示例在这里

cmake_minimum_required(VERSION 3.4)
project(cuism C)

set(WINDOWS_SDK_INCLUDES "C:/Program Files\ (x86)/Microsoft\  SDKs/Windows/v7.1A/Include/")
set(WINDOWS_SDK_LIBRARIES "C:/Program Files\ (x86)/Microsoft\ SDKs/Windows/v7.1A/Lib")
set(WSOCK "WSock32.lib")
set(ODBC "odbc32.lib")
set(ODBCCP "odbccp32.lib")

set(includeDir "${CMAKE_SOURCE_DIR}/include/")
set(resourceDir "${CMAKE_SOURCE_DIR}/resources/")


include_directories(
    ${includeDir}
    ${resourceDir}
)

set(CMAKE_LIBRARY_PATH ${WINDOWS_SDK_LIBRARIES})
set(CMAKE_INCLUDE_PATH ${WINDOWS_SDK_INCLUDES})


set(flags "/nologo /c /EHsc /GS- /MTd /Od /TC /Zi /Zp2 /D _USING_V110_SDK71_" )
set(CMAKE_C_FLAGS ${flags})

set(rc_flags /l0x809)
set(CMAKE_RC_FLAGS ${rc_flags})

set(linker_flags /NOLOGO /SUBSYSTEM:console /DLL)
set(CMAKE_LINKER_FLAGS ${linker_flags})

message(c flags are ${CMAKE_C_FLAGS})
message(rc flags are ${CMAKE_RC_FLAGS})
message(linker flags are ${CMAKE_LINKER_FLAGS})
message(linker EXE flags are ${CMAKE_EXE_LINKER_FLAGS})

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)


ADD_SUBDIRECTORY(cuimbct)
ADD_SUBDIRECTORY(cuimb)
ADD_SUBDIRECTORY(cuidll)

每个 sudb 目录都有一个类似于这个的 CMakeLists.txt

set(src cuimb.c "${includeDir}port.c" cuimben.c cuimb.rc)
add_library(cuimb SHARED ${src})
target_link_libraries(cuimb ${WSOCK} ${ODBC} ${ODBCCP})

由于错误代码 LNK2019,在链接阶段出错

【问题讨论】:

  • 到目前为止你尝试了什么?当上面的代码在project() 命令后面时,我会说它应该可以工作。有关更多详细信息,它对我有用的内容和方式,请参见例如here.
  • 尝试了 add_definitions() 和 add_compile_options() 方法
  • 只是一个猜测:您是否尝试在上面的代码中添加引号,例如set(flags "/nologo /c /EHsc /GS- /MTd /Od /TC /Zi /Zp2 /D _USING_V110_SDK71_")
  • 是的,我试过了
  • 请向minimal reproducible example 提供准确的错误消息。您当前的代码有明确的问题,它没有将编译器标志 together 括在引号中。 project() 调用的位置很关键,但你没有显示出来。

标签: cmake


【解决方案1】:

我已经尝试过您的代码 - 稍作修改 - 可以成功应用这些编译器/链接器选项。它包括我和@Tsyvarev 建议的更改(CMAKE_SHARED_LINKER_FLAGS 的引用和使用),并且我删除了对 Windows SDK 7.1 的静态引用。这可以使用-T 工具集选项进行设置:

> cmake -H"." -B"buildWin7" -T"v140_xp" -G"Visual Studio 14 2015" 
...

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(cuism C)

set(includeDir "${CMAKE_SOURCE_DIR}/include/")
set(resourceDir "${CMAKE_SOURCE_DIR}/resources/")

include_directories(
    ${includeDir}
    ${resourceDir}
)

set(flags "/nologo /c /EHsc /GS- /MTd /Od /TC /Zi /Zp2" )
set(CMAKE_C_FLAGS "${flags}")

set(rc_flags "/l0x809")
set(CMAKE_RC_FLAGS "${rc_flags}")

set(linker_flags "/NOLOGO /SUBSYSTEM:console /DLL")
set(CMAKE_SHARED_LINKER_FLAGS "${linker_flags}")

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

...

cuimb\CMakeLists.txt

...

add_library(cuimb SHARED ${src})
target_link_libraries(cuimb wsock32 odbc32 odbccp32)

推荐

为了保持您的 CMake 脚本代码干净,您应该将所有编译器/链接器选项移动到工具链文件中。我添加了一些我通常在那里定义的选项。另外,我将其简化为单个配置MyDebug(仅Debug 会附加其他调试选项),因为您的选项似乎不适用于Release

> cmake -H"." -B "buildWin7" -DCMAKE_TOOLCHAIN_FILE:PATH="VS2015Toolchain.cmake" -G"Visual Studio 14 2015" 
...

VS2015Toolchain.cmake

if (NOT CMAKE_GENERATOR_TOOLSET)
    set(CMAKE_GENERATOR_TOOLSET "v140_xp" CACHE INTERNAL "")
endif()

set(CMAKE_CONFIGURATION_TYPES "MyDebug" CACHE INTERNAL "")

# NOTE: Standard is a console app. If you need a windows app, 
#       use WIN32 define in add_executable
set(CMAKE_WIN32_EXECUTABLE 0 CACHE INTERNAL "")

set(CMAKE_C_FLAGS "/nologo /c /EHsc /GS- /MTd /Od /TC /Zi /Zp2 /W4" CACHE INTERNAL "")
set(CMAKE_RC_FLAGS "/l0x809" CACHE INTERNAL "")
set(
    CMAKE_SHARED_LINKER_FLAGS 
    "/NOLOGO /SAFESEH:NO /INCREMENTAL:NO /debug" 
    CACHE INTERNAL ""
)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH CACHE INTERNAL "")
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY CACHE INTERNAL "")
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE INTERNAL "")

【讨论】:

  • 感谢@Florian,一旦我将应用程序跨平台并拥有多个工具链,我就会使用这种方法。
  • @simon-p-r 不客气。请记住,CMAKE_GENERATOR_TOOLSET 只能在工具链中或通过-T 命令行参数设置。并注意您的活动构建配置。例如。 CMAKE_C_FLAGS_DEBUG 和朋友附加到CMAKE_C_FLAGS
  • 你的回答教会了我很多新东西,其中最重要的是 CMake 有一些选项不会显示,除非你 CMake --help-full (例如 -B 选项)编辑:实际上, -B 似乎是一个 CPack 选项。我想我不明白你对 -H 和 -B 标志的用法。 -H 用于寻求帮助,而 -B 未列为 CMake 选项。
  • @RichvonLehe 是的,-B-H 选项在 CMake 内部使用。所以它们是 - 即使它们被广泛使用并且非常有用 - 非官方且没有记录(另见Issue 0007872: Documentation missing "-H" and "-B" command line options)。不使用-B-H 的示例请参见here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 2022-10-05
  • 2012-06-18
  • 1970-01-01
相关资源
最近更新 更多