Sunday, October 18, 2009

Building c/c++ applications using GCC/G++ on iPhone

In order to save people the trouble that I had to go through, I am going to describe how I was able to build c and c++ code on the jailbroken iPhone, 3.0 firmware, using Cydia, and the GNU toolchain with gcc, g++, and make, as opposed to XCode. I'm a Linux user and don't have a Mac computer, so I'm not able to install and use the iPhone SDK, not to mention I don't feel like registering for all kinds of Apple junk.

So, without further delay here's what I did:
  1. Start with following the directions on antariz's blog: http://antirez.com/page/iphone-gcc-guide.html. Do what he says, including jailbreaking the phone, install the build tools in cydia which are mentioned (however, GCC won't work, so see #2), and download the header files from http://www.megaupload.com/?d=55ZNOCKI and put them on your phone somewhere.
  2. There are some problems with the antirez instructions. The first one is that GNU C Compiler cannot be installed in cydia because libgcc cannot be installed. Following the advice on http://modmyi.com/forums/iphone-ipod-touch-sdk-development-discussion/655111-compiling-iphone-3-0-a.html, download fake-libgcc at http://files.getdropbox.com/u/876743/fake-libgcc_1.0_iphoneos-arm.deb, and install it with dpkg -i fake-libgcc_1.0_iphoneos-arm.deb. Then you can install GCC from cydia.
  3. The downloaded header files need to be placed in a standard include directory. After you extract the include files onto your phone, you need to copy all of them to /usr/include.
  4. Ok, now you should be ready to build C program (C++ will come after.) So, make a simple hello world program:
    --------------------
    #include <stdio.h>
    int main() {
    printf("Hello\n");
    return 0;
    }
    --------------
    Save it as hello.c, or whatever you want.
  5. Build the program in the standard way:
    ----------------------------
    $> gcc hello.c -o hello
    -----------------------------
  6. When you try to execute the program with ./hello now, you will probably get the message:
    -------------------
    $> ./hello
    Killed
    -------------------
    This is because you need to sign applications written on the iPhone for whatever reason. To do this, you use the program ldid:
    --------------------
    $> ldid -S ./hello
  7. Now you can run your program normally.
  8. Next challenge is building C++ apps. EDIT: There are some c++ dependencies needed from Cygwin which were not mentioned in antariz's blog but are apparently needed. I have the following packages installed from Cydia, so not sure which are necessary and which aren't but you can try installing them:
    • C++ Standard Library
    • iPhone 2.0 Toolchain (thanks welf)
    • iPhone OS C/C++ Compiler
    • libsigc++
    • anything else that you can find in Cydia related to c++ if things don't work for you!
  9. By default g++ doesn't know where to look for the stl libraries, such as iostream etc. You need to set this up yourself. To do so, find where iostream is on your system by running:
    -------------------
    $> find / -name "iostream" -print
    ---------------------------
    It is in a whole bunch of places on my phone. /private/var/include/c++/4.0.0 seems like the most reasonable one, so I use that one. We need to add it to the standard C++ include dirs, so to do this we add to the environment variable CPLUS_INCLUDE_PATH. Another thing that g++ complains about needing is bits/c++config.h. For me it is in /private/var/include/c++/4.0.0/i686-apple-darwin9. So, we add those two directories to the CPLUS_INCLUDE_PATH:
    ----------------------------
    $> export CPLUS_INCLUDE_PATH=/private/var/include/c++/4.0.0:/private/var/include/c++/4.0.0/i686-apple-darwin9
    ----------------------------
  10. Now we can build C++ apps, since it can find the stl libraries. So if you have the source file:
    --------------------
    #include <iostream>
    using namespace std;
    int main() {
    cout << "Hello\n"; return 0; } --------------

    Now build and run it with:
    -------------------
    $> g++ hello.cpp -o hello
    $> ldid -S ./hello
    $> ./hello
    Hello
So there you go. Hopefully it works out for you. Note I was using iPhone OS 3.0. All commands were run using ssh into the iPhone. If you do it from the Terminal.App installed by cydia, make sure you run all commands as root, otherwise you may have permission problems to sort out.

Have fun!

39 comments:

  1. Thanks!
    Spent a while figuring out that I needed to install the 2.0 toolchain in order to find the right things at step 8. (Mine were in the same place though)
    I also kept getting the error:
    ld: library not found for -lstdc++
    but I think its been fixed by the symlink:
    ln -s /usr/lib/libstdc++.6.0.9.dylib /usr/lib/libstdc++.dylib

    ReplyDelete
  2. Is this guide based around the 3.0 firmware? It seems fake-libgcc does what it says on the tin and installs symlinks to nonexistent libgcc libraries. When I try to compile the C hello world it complains about those missing libraries, along the lines of:

    ld: library not found for -lgcc_s.10.5

    True enough, libgcc_s.10.5.dylib points to another libgcc_s.1.dylib, which doesn't exist.

    I'm guessing I've not follwed the instructions comprehensively or something is missing from this guide.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. This works great .. I also had to do what welf said for the g++ prog to work

    Here is all the stuff that I had to do:
    wget http://aaronash.com/iphone/fake-libgcc_1.0_iphoneos-arm.debdpkg -i fake-libgcc_1.0_iphoneos-arm.deb
    apt-get install com.bigboss.20toolchain
    apt-get install iphone-gcc
    export CPLUS_INCLUDE_PATH=/private/var/include/c++/4.0.0:/private/var/include/c++/4.0.0/i686-apple-darwin9

    ln -s /usr/lib/libstdc++.6.0.9.dylib /usr/lib/libstdc++.dylib

    ReplyDelete
  5. Yes, the instructions are based on the 3.0 firmware. Thanks for the comments on the additional steps needed to get g++ working. I think at one point out of desperation I basically installed everything in Cydia that had anything to do with c/c++ so that is why I may have missed a dependency in the instructions. Glad that others are able to get this working.

    ReplyDelete
  6. @JeremyG : could you contact me on rockinsquat-forever@hotm*il.c*m for some explanations, cause I've tried everything (changing the CPLUS_INCLUDE_PATHS to make it contain all the paths that I need) but that iostream.h couldn't still be founded at the g++ compilation. Thank you very much.

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Hi anonymous, just noticed in my example code that the #include section got screwed up (the editor didn't allow the "<",">" characters...) Anyway, you should include iostream like in step 9: #include <iostream> using namespace std; - not #include <iostream.h>, because iostream.h will likely not be found. Hope that helps.

    ReplyDelete
  9. it does not help! ;-) I know that one must do the include with .h cause the other way is deprecated. But even like this it doesn't work. That's why hoped we could have a quick chat to try to solve this issue. Comme tu veux.

    ReplyDelete
  10. sorry i meant: do the include WITHOUT the .h ;-)

    ReplyDelete
  11. Precision : btw on the step 8 you say that one should search iostream this way :

    find / -name "iostream" -print

    If I do so, I just find nothing, but

    find / -name "iostream.h" -print

    works ; but I don't think this as anathing to do with my actual problem

    ReplyDelete
  12. Heeeeeeeeelp ! ;-)

    ReplyDelete
  13. christian, what kind of phone and what OS version are you using? My instructions worked for a jailbroken 3.0 OS on an iphone 3G, do you have the same platform?

    ReplyDelete
  14. yes in fact I have a jailbroken 3G iPhone thought officially activatide, and I'm under 3.1.2, but I guess this doesn't change anything, according the to fact that gcc compiles everything perfectly but g++ not. Do you think that this behaviour can be really induced by being under 3.1.2 and not 3.0

    Christian

    ReplyDelete
  15. as i've asked before, and if you don't mind/have time, would it be possible to have a little chat by the way you want on that subject, cause you seem to be quite advanced in the same thing that i'm trying to do (and it would allow to maybe close the issue faster) ; thank you very much

    Christian

    PS : the headers i'm actually using are from the XCode iPhoneOS 3.0 (gcc worked also with the 2.0 headers; g++ don't work with the both ...)

    ReplyDelete
  16. So, no solution ?... I'm startng to ask myself if someone really succeeded in compiling c++ files with g++ on iPhone ! ;-) ;-) ;-) No seriously, any idea ?...

    ReplyDelete
  17. By the way, does anyone know if one can find somewhere an Xcode template allowing to manage all that stuff more easily, and for instance doing the same but with cross-compilation, so that the iPhone hasn't to compile anything ? Thx

    Christian

    ReplyDelete
  18. For cross compiling I tried the instructions on Saurik's site at http://www.saurik.com/id/4. Those are the best non-Mac instructions that I have found, but unfortunately I could not quite get it working, and don't have time to pursue it right now. If you get it working please let me know as I would be interested to know how. The iPhone doesn't have enough memory to compile large c++ programs, so cross-compiling is essential for building useful libraries on the iPhone.

    ReplyDelete
  19. Hello Jeremy,

    I've tried the Saurik thing already, it worked pretty easy for me, but it was 2 years ago, so I do not remember all the issues that I've had to solve then (by the way Saurik helped me for that). I wouldn't advise you to persist in that direction cause there's now (in fact since one year) a simplest way to do the same (I'm sending the web page to you right now on gmail cause cannot succeed in damn pasting it here!) You'll see that the guy uses the toolchain for that purpose ; if you see a way doing it with the official c'n'c++ header from the 3.xx SDK, I'm quite interested.

    Christian

    ReplyDelete
  20. i have installed all but i can´t find "Idid" anywhere. is it in an special repo?! or do i have to do something to find it?^^

    ReplyDelete
  21. not Idid , should be ldid

    ReplyDelete
  22. Thanks a lot.
    it was very use full and worked for me.
    i'm a windows user and now i can develop for my phone.

    ReplyDelete
  23. hola yo tengo el mismo problema que welf. Cuando compilo(c++) me sale el siguiente error:

    ld: library not found for -lstdc++

    Como puedo solucionarlo?
    me gustaria mucho poder compilar i executar mis programas en el iphone.
    gracias

    ReplyDelete
  24. Sorry
    Hi I have the same problem as Welf. When compiling (c + +) I get the following error:

    ld: library not found for -lstdc++

    How I can fix it?
    I would love to compile i execute my programs on the iphone.
    thanks

    ReplyDelete
  25. ElMaskina: did you try what welf said: ln -s /usr/lib/libstdc++.6.0.9.dylib /usr/lib (the path for you may be different depending on the version number). Also make sure all dependencies in step 8 are installed.

    ReplyDelete
  26. I installed all dependences in step 8:
    C++ Standard Library
    -iPhone 2.0 Toolchain (thanks welf)--> warning that say files installed to /User
    -iPhone OS C/C++ Compiler
    -libsigc++
    -anything else that you can find in Cydia related to c++ if things don't work for you!--> All that say c++ at development section in cydia.
    How I now my version number?

    ReplyDelete
  27. hi! i have been installed the iphone os c/c++, libgcc, GNU Complier, but when i open the mterminal and type "compiler", appear a message, that say: type s followed enter to write a code" (not remenber the words exactly) i type "s" and say : "sh: nano: command not found" help me please, i need it to compile some exe. my mail carlos_loscar27@hotmail.com

    ReplyDelete
  28. This also works on 4.1 on my iPod Touch 2G MC, though I was missing the libstdc++.dylib. I simply copied it over from my SDK at /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.1/Symbols/usr/lib/libstdc++.6.0.9.dylib to /usr/lib/ on my iPod.

    ReplyDelete
  29. Quick Question, how would I go about uploading the apps I make with gcc to Cydia?

    ReplyDelete
  30. Check this if you have a problem with lstdc++
    I think the zip file that you patch to /use/lib is missing
    libstdc++.6.0.9.dylib

    I found that the zip has only 3 file
    1. libgcc_s.1.dylib
    2. libSystem.B.dylib
    3. libSystem.dylib

    4. libstdc++.6.0.9.dylib <------------ missing

    http://gamma-level.com/iphoneos/ports/environment

    ReplyDelete
  31. Thank you fucking so much man :D
    Now I can do something sinful with my iPad:P

    ReplyDelete
  32. Your article has proven useful to me. It’s very informative and you are obviously very knowledgeable in this area. You have opened my eyes to varying views on this topic
    with interesting and solid content.
    web application development

    ReplyDelete
  33. This comment has been removed by the author.

    ReplyDelete
  34. Thank you so much but where else can i download the header files, the link you provided nolonger works

    ReplyDelete
  35. maybe this is a stupid question, but... did you find a way to get at the interesting stuff on the iphone? e.g. is there a .h somewhere you can include that gives you the interface to the accelerometer? Or something like that?
    Thanks.

    ReplyDelete
  36. when I run the compiler and choose to write a new code,it says press s followed by enter to start writing abut when i do so,it says enter the name of the file you saved with the nano.
    I need help please

    ReplyDelete
  37. Dear,
    i have followed your : http://gamma-level.com/iphoneos/ports/environment

    i used the following command to set path:
    export CPLUS_INCLUDE_PATH=/var/include/c++/4.0.0://var/include/c++/4.0.0/i686-apple-darwin9

    installed C++ standared library which automatically install libstdc++.dylib into /usr/lib
    but yet i created sym link of libstdc++.6.dylib

    gcc runs well but g++ test.cpp -o test gives

    ld: library not found for -lstdc++
    collect2: ld returned 1 exit status



    normally lstdc++ is looking for libstdc++ which is already in /usr/lib

    what's wrong?

    ReplyDelete