[CMake] Adding Mac OS X Style Frameworks On Linux

Karol Krizka kkrizka at gmail.com
Tue Mar 30 20:48:37 EDT 2010


Hi there,

I am trying to use CMake to develop Apps for a jailbroken iPhone using
the iphonedevonlinux toolchain[1]. I got the toolchain to work and
build the included test app, HelloToolchain. What I am trying to do
next is write a CMakeLists.txt for this test App. I renamed it as
KKToolchain for CMake enabled testing. Anyways, if you want to see
what the Makefile should look like, see here[2].

The way I am trying to accomplish is to use CMake's Cross Compiling
support[3]. As per the WiKi entry, I've created a toolchain file
called Toolchain-iphone.cmake and filled it in with the following:

SET(CMAKE_SYSTEM_NAME Darwin)
SET(CMAKE_SYSTEM_VERSION 9)
SET(CMAKE_SYSTEM_PROCESSOR arm-apple-darwin9)
SET(IPHONE_TOOLCHAIN_DIR /home/kkrizka/Sources/iphonedevonlinux/toolchain)
SET(CMAKE_C_COMPILER
${IPHONE_TOOLCHAIN_DIR}/pre/bin/${CMAKE_SYSTEM_PROCESSOR}-gcc)
SET(CMAKE_CXX_COMPILER
${IPHONE_TOOLCHAIN_DIR}/pre/bin/${CMAKE_SYSTEM_PROCESSOR}-g++)
SET(CMAKE_FIND_ROOT_PATH  ${IPHONE_TOOLCHAIN_DIR})
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

As for the CMakeLists.txt file, I used the following:

PROJECT(KKToolchain)
SET(KKToolchain_SOURCES src/KKToolchain.m)
SET(KKToolchain_LIBRARIES objc)
ADD_EXECUTABLE(KKToolchain ${KKToolchain_SOURCES})
TARGET_LINK_LIBRARIES(KKToolchain ${KKToolchain_LIBRARIES})
SET(CMAKE_EXE_LINKER_FLAGS "-bind_at_load -framework Foundation
-framework CoreFoundation -framework UIKit -w")

After I compile the binary, I manually create a bundle and copy it to
my iPhone using the commands from the HelloToolchain Makefile. I plan
to find a way to automate this in CMake later. But right now, this
works perfectly.

Next, I would like to add a way to link against the different
frameworks using a macro without having to modify
CMAKE_EXE_LINKER_FLAGS.
For example, I want to replace this:
SET(CMAKE_EXE_LINKER_FLAGS "-bind_at_load -framework Foundation
-framework CoreFoundation -framework UIKit -w")
by this:
TARGET_ADD_FRAMEWORKS(KKToolchain Foundation CoreFoundation UIKit)

One suggestion I found way to use the TARGET_ADD_LIBRARIES macro[4] to
add the frameworks. On Mac OS X this should work, but it does not work
on Linux. My question is, is it possible to trick CMake thinking that
it is working in an Mac OSX environment, so it would correctly add the
frameworks at the linking stage?

I tried a macro that I found on StackOverflow[5]. Basically, I've
added the following at the end of my CMakeLists.txt

SET(CMAKE_OSX_SYSROOT ${IPHONE_TOOLCHAIN_DIR}/sys)
MACRO(ADD_FRAMEWORK fwname appname)
  FIND_LIBRARY(FRAMEWORK_${fwname}
    NAMES ${fwname}
    PATHS ${CMAKE_OSX_SYSROOT}/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)
ADD_FRAMEWORK(Foundation KKToolchain)

The output is as follows:

kkrizka at sein:~/Sources/iphonedevonlinux/apps/KKToolchain/build$ cmake
-DCMAKE_TOOLCHAIN_FILE=../Toolchain-iphone.cmake ..
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler:
/home/kkrizka/Sources/iphonedevonlinux/toolchain/pre/bin/arm-apple-darwin9-gcc
-- Check for working C compiler:
/home/kkrizka/Sources/iphonedevonlinux/toolchain/pre/bin/arm-apple-darwin9-gcc
-- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler:
/home/kkrizka/Sources/iphonedevonlinux/toolchain/pre/bin/arm-apple-darwin9-g++
-- Check for working CXX compiler:
/home/kkrizka/Sources/iphonedevonlinux/toolchain/pre/bin/arm-apple-darwin9-g++
-- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Framework Foundation found at
/home/kkrizka/Sources/iphonedevonlinux/toolchain/sys/System/Library/Frameworks/Foundation.framework
-- Configuring done
WARNING: Target "KKToolchain" requests linking to directory
"/home/kkrizka/Sources/iphonedevonlinux/toolchain/sys/System/Library/Frameworks/Foundation.framework".
 Targets may link only to libraries.  CMake is dropping the item.
-- Generating done
-- Build files have been written to:
/home/kkrizka/Sources/iphonedevonlinux/apps/KKToolchain/build

As you can see, it correctly finds the Foundation framework in my
toolchain. But it complains when I try to link to it. I am assuming
that this is because linking to frameworks in only supported on Mac OS
X. Is this true? If so, is there some other way around it?

Cheers,
Karol Krizka
http://www.krizka.net

[1] http://code.google.com/p/iphonedevonlinux/
[2] http://code.google.com/p/iphonedevonlinux/source/browse/trunk/apps/HelloToolchain/Makefile
[3] http://www.cmake.org/Wiki/CMake_Cross_Compiling
[4] http://www.cmake.org/pipermail/cmake/2009-October/032661.html
[5] http://stackoverflow.com/questions/822404/how-to-set-up-cmake-to-build-an-app-for-the-iphone


More information about the CMake mailing list