CMake跨编译问题:链接器中的CXX_FLAGS。

4
我在Mac OS X上拥有以下用于iPhone交叉编译的工具链:
# Platform Info
SET (CMAKE_SYSTEM_VERSION 1)
SET (CMAKE_SYSTEM_PROCESSOR arm)

# SDK Info
SET (SDKVER "3.0")
SET (DEVROOT "/Developer/Platforms/iPhoneOS.platform/Developer")
SET (SDKROOT "${DEVROOT}/SDKs/iPhoneOS${SDKVER}.sdk")
SET (CMAKE_OSX_SYSROOT "${SDKROOT}")
SET (CMAKE_OSX_ARCHITECTURES "armv6")
SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)

# C Compiler
SET (CMAKE_C_COMPILER "${DEVROOT}/usr/bin/arm-apple-darwin9-gcc-4.2.1")
#SET (LINK_FLAGS "-arch armv6 -arch armv7")
#SET (CMAKE_C_LINK_EXECUTABLE "${DEVROOT}/usr/bin/g++-4.2")
SET (CMAKE_C_FLAGS "-x objective-c")
SET (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -DDEBUG=1 -ggdb")
SET (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -DNDEBUG=1")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -DNDEBUG=1 -ggdb")

# CXX Compiler
SET (CMAKE_CXX_COMPILER "${DEVROOT}/usr/bin/arm-apple-darwin9-g++-4.2.1")
SET (CMAKE_CXX_FLAGS "-x objective-c++")
SET (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -DDEBUG=1 -ggdb")
SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG=1")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -ggdb")

# Definitions
#ADD_DEFINITIONS("-arch armv6")
#ADD_DEFINITIONS("-arch armv7")
ADD_DEFINITIONS("-pipe")
ADD_DEFINITIONS("-no-cpp-precomp")
ADD_DEFINITIONS("--sysroot=${SDKROOT}")
ADD_DEFINITIONS("-miphoneos-version-min=${SDKVER}")

# System Includes
INCLUDE_DIRECTORIES(SYSTEM "${SDKROOT}/usr/include")
INCLUDE_DIRECTORIES(SYSTEM "${SDKROOT}/usr/include/c++/4.2.1")
INCLUDE_DIRECTORIES(SYSTEM "${SDKROOT}/usr/include/c++/4.2.1/armv6-apple-darwin9")
INCLUDE_DIRECTORIES(SYSTEM "${SDKROOT}/opt/iphone-${SDKVER}/include")
INCLUDE_DIRECTORIES(SYSTEM "${SDKROOT}/usr/local/iphone-${SDKVER}/include")

# System Libraries
LINK_DIRECTORIES("${SDKROOT}/usr/lib")
LINK_DIRECTORIES("${SDKROOT}/usr/lib/gcc/arm-apple-darwin9/4.2.1/")
#LINK_DIRECTORIES("${SDKROOT}/opt/iphone-${SDKVER}/lib")
#LINK_DIRECTORIES("${SDKROOT}/usr/local/iphone-${SDKVER}/lib")

# Root Paths
SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "/opt/iphone-${SDKVER}/" "/usr/local/iphone-${SDKVER}/")
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
SET (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

# CMake Parameters
SET (iPhone 1)
SET (iPhoneOS 1)
SET (iPhoneOS_VERSION ${SDKVER})
SET (CMAKE_CROSSCOMPILING 1)

#SET_TARGET_PROPERTIES(p3dm PROPERTIES LINK_FLAGS "-arch armv6 -arch armv7")

# HELPERS
#---------

MACRO(ADD_FRAMEWORK appname fwname)
    find_library(FRAMEWORK_${fwname}
        NAMES ${fwname}
        PATHS ${SDKROOT}/System/Library
        PATH_SUFFIXES Frameworks
        NO_DEFAULT_PATH)
    if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND)
        MESSAGE(ERROR ": Framework ${fwname} not found")
    else()
        TARGET_LINK_LIBRARIES(${appname} ${FRAMEWORK_${fwname}})
        MESSAGE(STATUS "Framework ${fwname} found at ${FRAMEWORK_${fwname}}")
    endif()
endmacro(ADD_FRAMEWORK)

我使用以下的CMakeLists.txt文件:

# PROJECT PARAMETERS
#--------------------

SET(APP_NAME p3dm)
PROJECT(${APP_NAME})

# SOURCE CODE
#-------------

SET(CMAKE_CXX_FLAGS "-x objective-c++")

INCLUDE_DIRECTORIES(SYSTEM ../inc/ ../xsrc/)

FILE(GLOB headers ../src/*.h ../xsrc/*.h)
FILE(GLOB sources ../src/*.cpp ../xsrc/*.c ../xsrc/*.cpp)

#set_source_files_properties(${sources} PROPERTIES LANGUAGE C )

# EXECUTABLE
#------------

SET(MACOSX_BUNDLE_GUI_IDENTIFIER "org.reversity.${APPNAME}")
SET(APP_TYPE MACOSX_BUNDLE)

ADD_EXECUTABLE(${APP_NAME} ${APP_TYPE} ${headers} ${sources})

SET_TARGET_PROPERTIES(${APP_NAME} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer: Mario Hros")

# FRAMEWORKS
#------------

ADD_FRAMEWORK(${APP_NAME} UIKit)

我使用以下编译Bash脚本:
```bash ```
#!/bin/bash

unset CPATH
unset C_INCLUDE_PATH
unset CPLUS_INCLUDE_PATH
unset OBJC_INCLUDE_PATH
unset LIBS
unset DYLD_FALLBACK_LIBRARY_PATH
unset DYLD_FALLBACK_FRAMEWORK_PATH

export SDKVER="3.0"
export DEVROOT="/Developer/Platforms/iPhoneOS.platform/Developer"
export SDKROOT="$DEVROOT/SDKs/iPhoneOS$SDKVER.sdk"
export PKG_CONFIG_PATH="$SDROOT/usr/lib/pkgconfig":"/opt/iphone-$SDKVER/lib/pkgconfig":"/usr/local/iphone-$SDKVER/lib/pkgconfig"
export PKG_CONFIG_LIBDIR="$PKG_CONFIG_PATH"
export MAINFOLDER=`pwd`

cmake . \
                         -DCMAKE_TOOLCHAIN_FILE="$MAINFOLDER/cmake/iphone-$SDKVER.toolchain" \
                         -DCMAKE_INSTALL_PREFIX="/opt/iphone-$SDKVER" \
                         "$@"

问题在于,在链接器中也使用了CMAKE_CXX_FLAGS。编译没有问题。链接看起来也很好,它添加了正确的-framework标志,但是还添加了CMAKE_CXX_FLAGS(这些标志是-x objective-c++),因此它的行为类似于编译objective c++(-x objective-c++),并且无法链接这些对象文件。
我遇到了以下错误:
ComponentManager.cpp.o:20: error: stray '\341' in program

你不知道我做错了什么吗?

3个回答

3

这不完全是我感兴趣的内容。为什么CMAKE_C_FLAGS要传递给链接器呢?它不应该只针对编译器吗? - k3a
1
在我看来,应该是这样的,但是CMake也会将其传递给链接器,如果您查看文档,它说它将传递您使用的最高级别语言的CMAKE_???_FLAGS,即如果您的项目中有1个C++文件,则将传递CMAKE_CXX_FLAGS,否则将传递CMAKE_C_FLAGS。 - Gianni

3
我通过从工具链文件中删除CMAKE_CXX_FLAGS和CMAKE_C_FLAGS,并在CMakeLists.txt中添加ADD_DEFINITIONS(“-x objective-c ++”)来解决了这个问题。
这样,-x objective-c ++标志仅传递给编译器(而不是链接器),并且仅针对我的源代码(而不是在构建我的目标之前进行的cmake测试编译)。

2
ADD_DEFINITIONS 应该只用于预处理器定义。以这种方式使用它可能会在未来引起其他问题。请参见http://www.cmake.org/Bug/view.php?id=12871#c28234获取源代码。 - Sam Morris

2
链接命令行设置在Modules/CMake{C,CXX,Fortran}Information.cmake中,默认使用编译器及其编译标志来进行链接(参见源代码)。可以通过替换构建链接命令行的规则来改变这一点,该规则存储在变量CMAKE_CXX_LINK_EXECUTABLE(以及相关变量)中。该变量并不提供链接器可执行文件,而是说明如何链接可执行文件!
其中一个解决方案是设置一个修改后的规则,避免使用CXX标志,例如:
cmake -DCMAKE_CXX_LINK_EXECUTABLE="<CMAKE_CXX_COMPILER> <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")

然而,您可以通过不在第一次设置CMAKE_CXX_FLAGS,而是将COMPILE_FLAGS属性添加到目标来避免该问题。

谢谢mabraham。这是非常有用的回复。我处于稍微不同的情况下,我有不同的C、CXX编译选项。COMPILE_FLAGS没有COMPILE_<LANG>FLAGS。设置CMAKE<LANG>_FLAGS不是一个选择,因为它们也被传递给链接器。所以你的建议帮助我解决了我的问题。 - leodotcloud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接