4

I have following toolchain for iPhone crosscompilation on mac os x:

# 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) 

And i use following 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) 

I use following compilation bash script:

#!/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" \ "$@" 

The problem is, that it uses CMAKE_CXX_FLAGS also in linker. Compilation is fine. Linking looks fine, it adds correct -framework flags, but also adds CMAKE_CXX_FLAGS (which are -x objective-c++) so instead of linking object files compiled previously it behaves like compiling objective c++ (-x objective-c++) and it is impossible to link these objects.

I am getting errors like

ComponentManager.cpp.o:20: error: stray '\341' in program 

Don't you know what I am doing wrong?

3 Answers 3

3

You can set the LINKER_LANGUAGE to C to force CMake to use the CMAKE_C_FLAGS for the linker. Check it out here.

Sign up to request clarification or add additional context in comments.

2 Comments

It is not exactly what I was interested in. Why are CMAKE_C_FLAGS passed to linker at all? Shouldn't it be only for compiler?
Yeah, in my opinion it should, but CMake passes it to linker too, and if you check the docs, it says that it'll pass the CMAKE_???_FLAGS of the highest level language you used, i.e. if you have 1 C++ file in your project, CMAKE_CXX_FLAGS will be passed, otherwise, it'll be CMAKE_C_FLAGS.
3

I've solved this problem by removing CMAKE_CXX_FLAGS and CMAKE_C_FLAGS from the toolchain file and adding ADD_DEFINITIONS("-x objective-c++") to CMakeLists.txt.

That way -x objective-c++ flags get passed only to the compiler (not linker) and only for my source code (not cmake test compilation which happens before building my target).

1 Comment

ADD_DEFINITIONS should only be used for preprocessor definitions. Using it in this way may cause other problems in the future. See cmake.org/Bug/view.php?id=12871#c28234 for the source.
2

The link command line is set in Modules/CMake{C,CXX,Fortran}Information.cmake and defaults to using the compiler and its compilation flags (see source code). This can be changed by replacing the rule that builds the link command line, which lives in variables CMAKE_CXX_LINK_EXECUTABLE (and friends). That variable does not give the linker executable; it says how to link an executable!

One solution is to set a modified form of that rule that avoids the use of CXX flags, e.g.

cmake -DCMAKE_CXX_LINK_EXECUTABLE="<CMAKE_CXX_COMPILER> <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") 

However, you can avoid the problem by not setting CMAKE_CXX_FLAGS in the first place, but rather adding COMPILE_FLAGS property to the target.

1 Comment

Thanks mabraham. This was a very useful reply. I was in a slightly different situation, I had different compile options for C, CXX. COMPILE_FLAGS didn't have a COMPILE_<LANG>_FLAGS. Setting CMAKE_<LANG>_FLAGS was not an option as they were being passed to the linker as well. So your suggestion helped solve my problem.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.