View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0010526CMakeCMakepublic2010-04-08 20:562010-05-01 14:42
ReporterKarol Krizka 
Assigned ToAlex Neundorf 
PrioritynormalSeverityminorReproducibilityalways
StatusclosedResolutionfixed 
PlatformOSOS Version
Product VersionCMake-2-8 
Target VersionFixed in Version 
Summary0010526: Adding Mac OS X Style Frameworks On Linux Does Not Work
DescriptionI 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 asKKToolchain 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 tomy 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 asked this question on the CMake mailing list[5] and I was told that this should be possible. Since it is not working, it was recommended that I file a bug report.

I tried a macro that I found on StackOverflow[6]. 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@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.

[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://www.cmake.org/pipermail/cmake/2010-April/036340.html [^]
[6] http://stackoverflow.com/questions/822404/how-to-set-up-cmake-to-build-an-app-for-the-iphone [^]
Additional InformationCMake: 2.8.0
OS: Ubuntu Linux 9.04 (Karmic Koala)
TagsNo tags attached.
Attached Filespatch file icon cmake-git-frameworks-on-nonapple-darwin.patch [^] (806 bytes) 2010-04-15 23:59 [Show Content]
patch file icon cmake-git-frameworks-on-nonapple-darwin-2.patch [^] (6,781 bytes) 2010-04-21 18:04 [Show Content]
patch file icon cmake-git-frameworks-on-nonapple-darwin-3.patch [^] (2,560 bytes) 2010-04-29 23:52 [Show Content]

 Relationships

  Notes
(0020200)
Karol Krizka (reporter)
2010-04-15 23:58

The problem was that there was an "ifdef __APPLE__" before a framework was added. I've changed it to "if(systemName=="Darwin")" as was suggested on the mailing list by Alexander Neundorf. Patch against the current git master is attached.
(0020263)
Alex Neundorf (developer)
2010-04-19 14:43

If you search for "System/Library" in the cmake sources, you'll find a few more places with special handling for frameworks, most of them ifdef'ed.

There is one in cmLocalGenerator.cxx. Does your cross compiling toolchain recognize the "-F" flag for linking against frameworks ?
If that's the case, then you probably want to do basically the same thing there too.

Then there is one in cmMakefileTargetGenerator.cxx, I guess there it's the same.

The one in the XCode generator shouldn't matter.

And finally the one in void cmComputeLinkInformation::ComputeFrameworkInfo()...
not sure, you have to check.

Can you have a look at these places and post a patch once it is working for you ? (I applied your patch already locally here).

Alex
(0020337)
Alex Neundorf (developer)
2010-04-21 15:04

Ok, I committed your patch.
Could you please also have a look at the other places I mentioned ?

Alex
(0020340)
Karol Krizka (reporter)
2010-04-21 18:03

Hi, sorry for the late reply, but it is exam season at my unversity.

Anyways, using the latest checkout of the master branch, the following command is executed when linking:

/home/kkrizka/Sources/iphonedevonlinux/toolchain/pre/bin/arm-apple-darwin9-g++ -Wl,-search_paths_first -headerpad_max_install_names CMakeFiles/KKToolchain.dir/src/KKToolchain.m.o -o KKToolchain -F/home/kkrizka/Sources/iphonedevonlinux/toolchain/sys/System/Library/Frameworks -lobjc -framework Foundation -framework CoreFoundation -framework UIKit

So it does add the -F flag to locate the frameworks.

Now I just grepped through all of the cxx file, looking for if(n)def APPLE blocks and seeing if any of them are dealing with frameworks and "fixed" them. The only one I had trouble with was cmFindCommon.cxx, whose constructor contains the following code:
#if defined(__APPLE__)
  this->SearchFrameworkFirst = true;
  this->SearchAppBundleFirst = true;
#else
  this->SearchFrameworkFirst = false;
  this->SearchAppBundleFirst = false;
#endif
The problem with using systemName=="Darwin" here is that no Makefile has been defined yet, so I cannot get the systemName. I tried to solve this by overriding the SetMakefile function and checking there. I am not sure if this is a good solution, but I included it in the patch anyways and you can choose if to accept it or not.

But doing this did not seem to make any difference, at least not for my limited test case. After I apply this patch, the following command is executed:

/home/kkrizka/Sources/iphonedevonlinux/toolchain/pre/bin/arm-apple-darwin9-g++ -Wl,-search_paths_first -headerpad_max_install_names CMakeFiles/KKToolchain.dir/src/KKToolchain.m.o -o KKToolchain -F/home/kkrizka/Sources/iphonedevonlinux/toolchain/sys/System/Library/Frameworks -lobjc -framework Foundation -framework CoreFoundation -framework UIKit
(0020442)
Alex Neundorf (developer)
2010-04-27 15:54

I think it looks good.
Just one thing. Brad just told me that he would prefer
if(this->Makefile->IsOn("APPLE"))
over if(systemName=="Darwin")
since this is already used in other places.

Can you please post an updated patch ?

Thanks
Alex
(0020505)
Alex Neundorf (developer)
2010-05-01 14:42

Thanks for the patch.
I committed and pushed to git master.

Alex

 Issue History
Date Modified Username Field Change
2010-04-08 20:56 Karol Krizka New Issue
2010-04-15 23:58 Karol Krizka Note Added: 0020200
2010-04-15 23:59 Karol Krizka File Added: cmake-git-frameworks-on-nonapple-darwin.patch
2010-04-18 04:48 Alex Neundorf Status new => assigned
2010-04-18 04:48 Alex Neundorf Assigned To => Alex Neundorf
2010-04-19 14:43 Alex Neundorf Note Added: 0020263
2010-04-21 15:04 Alex Neundorf Note Added: 0020337
2010-04-21 18:03 Karol Krizka Note Added: 0020340
2010-04-21 18:04 Karol Krizka File Added: cmake-git-frameworks-on-nonapple-darwin-2.patch
2010-04-27 15:54 Alex Neundorf Note Added: 0020442
2010-04-29 23:52 Karol Krizka File Added: cmake-git-frameworks-on-nonapple-darwin-3.patch
2010-05-01 14:42 Alex Neundorf Note Added: 0020505
2010-05-01 14:42 Alex Neundorf Status assigned => closed
2010-05-01 14:42 Alex Neundorf Resolution open => fixed


Copyright © 2000 - 2018 MantisBT Team