Sunday, October 30, 2011

How to install perl, theos and iphone-gcc in iPhone

(1) Install the following packages in Cydia
APT 0.6 Transitional (and all its dependencies)
wget

(2) Use SSH login shell commands to install perl & theos (or install them in Cydia by adding Sources)

echo "deb http://coredev.nl/cydia iphone main" > /etc/apt/sources.list.d/coredev.nl.list
wget http://coredev.nl/cydia/coredev.pub
apt-key add coredev.pub
apt-get update
apt-get install perl
echo "deb http://nix.howett.net/theos ./" > /etc/apt/sources.list.d/howett.net.list
apt-get update
apt-get install net.howett.theos rsync


If you have No space left on device error when installing perl , relocate /usr/local to /var/stash/local

(3) Use SSH login shell commands to install iphone-gcc and ldid (or install them in Cydia)

wget http://apt.saurik.com/debs/libgcc_4.2-20080410-1-6_iphoneos-arm.deb
dpkg -i libgcc_4.2-20080410-1-6_iphoneos-arm.deb
apt-get update
apt-get install iphone-gcc
apt-get install make ldid zip unzip com.ericasadun.utilities


(4) Download SDK3.2 Headers and Libs from here
Please take note that the current iPhone-gcc does not support iOS SDK 4.0 or above

(5) copy iPhoneSDKHeadersAndLibs_32.pkg to iPhone

(6) Install SDK and additional libraries to sdk

apt-get update
apt-get install xar cpio
xar -xf iPhoneSDKHeadersAndLibs_32.pkg Payload
cat Payload | zcat | cpio -id
mv Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk /var/sdk
cd /var/sdk/usr/lib/
ln -s libstdc++.6.dylib libstdc++.dylib
ln -s crt1.o crt1.10.5.o
ln -s dylib1.o dylib1.10.5.o
cp -p /usr/lib/libgcc_s.10.5.dylib .



(7) Create a command line tool project

/var/theos/bin/nic.pl helloworld


(8) Choose [4.] iphone/tool

(9) Edit main.mm and add printf and cout like this
main.mm Select all

#include <iostream>
using namespace std;
int main(int argc, char **argv, char **envp) {
    printf("Hello World\n");
    cout << "Hello CPP" << endl;
    return 0;
}


(10) Add the ADDITIONAL_CFLAGS and ADDITIONAL_CCFLAGS in Makefile like this
Makefile (Tool) Select all

export THEOS=/var/theos
include $(THEOS)/makefiles/common.mk

TOOL_NAME = helloworld
helloworld_FILES = main.mm

ADDITIONAL_CFLAGS = -I"$(SYSROOT)/usr/lib/gcc/arm-apple-darwin10/4.2.1/include"
ADDITIONAL_CCFLAGS = -I"$(SYSROOT)/usr/include/c++/4.2.1"
ADDITIONAL_CCFLAGS += -I"$(SYSROOT)/usr/include/c++/4.2.1/armv6-apple-darwin10"

include $(THEOS_MAKE_PATH)/tool.mk



(11) Make and test run

cd helloworld
make clean
make
./obj/helloworld


(12) For app, the sample Makefile is
Makefile (Application) Select all

export THEOS=/var/theos
include $(THEOS)/makefiles/common.mk

APPLICATION_NAME = myapp
myapp_FILES = main.m
myapp_FILES += $(wildcard Classes/*.m)

myapp_FRAMEWORKS = UIKit

PCH:=$(wildcard *.pch)

ADDITIONAL_CFLAGS = -I"$(SYSROOT)/usr/lib/gcc/arm-apple-darwin10/4.2.1/include"
ADDITIONAL_CCFLAGS = -I"$(SYSROOT)/usr/include/c++/4.2.1"
ADDITIONAL_CCFLAGS += -I"$(SYSROOT)/usr/include/c++/4.2.1/armv6-apple-darwin10"
ifneq ($(PCH),)
ADDITIONAL_CFLAGS += -include $(PCH)
ADDITIONAL_CCFLAGS += -include $(PCH)
endif

include $(THEOS_MAKE_PATH)/application.mk

RESOURCESFOLDER=./Resources
PAYLOADFOLDER=$(THEOS_STAGING_DIR)
OBJFOLDER=./obj
INFOPLIST:=$(wildcard *Info.plist)
INFOPLIST+=$(wildcard Resources/*Info.plist)
PNGFILES:=$(wildcard Resources/*.png)
LPROJFILES:=$(wildcard Resources/*.lproj)
APPVERSION=$(shell plutil -key CFBundleVersion $(INFOPLIST) 2>&1)

# make ipa
# replace 4 spaces with TAB for below
ipa:    stage
    rm -fr $(PAYLOADFOLDER)/* $(APPLICATION_NAME)_$(APPVERSION).ipa
    rm -f Payload
    mkdir -p $(PAYLOADFOLDER)/$(APPLICATION_NAME).app
    cp $(OBJFOLDER)/$(APPLICATION_NAME) $(PAYLOADFOLDER)/$(APPLICATION_NAME).app/.
ifneq ($(PNGFILES),)
    cp -rp $(RESOURCESFOLDER)/*.png $(PAYLOADFOLDER)/$(APPLICATION_NAME).app/.
endif
ifneq ($(LPROJFILES),)
    cp -rp $(RESOURCESFOLDER)/*.lproj $(PAYLOADFOLDER)/$(APPLICATION_NAME).app/.
endif
    @echo "APPL????" > $(PAYLOADFOLDER)/$(APPLICATION_NAME).app/PkgInfo
    cp -p $(INFOPLIST) $(PAYLOADFOLDER)/$(APPLICATION_NAME).app/.
    ln -sf $(PAYLOADFOLDER) Payload
    zip -r $(APPLICATION_NAME)_$(APPVERSION).ipa Payload > /dev/null


(13) For mobilesubstrate extension, the sample Makefile is
Makefile (Tweak) Select all

export THEOS=/var/theos
include $(THEOS)/makefiles/common.mk

TWEAK_NAME = mytweak
APP_ID = com.mycompany.mytweak
mytweak_FILES = Tweak.xm
mytweak_FRAMEWORKS = UIKit

ADDITIONAL_CFLAGS = -I"$(SYSROOT)/usr/lib/gcc/arm-apple-darwin10/4.2.1/include"
ADDITIONAL_CCFLAGS = -I"$(SYSROOT)/usr/include/c++/4.2.1"
ADDITIONAL_CCFLAGS += -I"$(SYSROOT)/usr/include/c++/4.2.1/armv6-apple-darwin10"

include $(THEOS_MAKE_PATH)/tweak.mk

# make package
# replace 4 spaces with TAB for below
after-stage::
    find $(THEOS_STAGING_DIR) -iname '*.plist' -exec plutil -convert binary1 {} \;
    $(FAKEROOT) chown -R 0:80 $(THEOS_STAGING_DIR)

PACKAGEFOLDER=./layout
CONTROLFILE=control
PACKAGENAME=$(shell grep ^Package: $(CONTROLFILE) | cut -d ' ' -f 2)
PACKAGEVERSION=$(shell grep ^Version: $(CONTROLFILE) | cut -d ' ' -f 2)
ARCH=$(shell grep ^Architecture: $(CONTROLFILE) | cut -d ' ' -f 2)
OBJFOLDER=./obj
_EXCLUDES ?= tmp _MTN .git .svn .DS_Store ._*
_EXCLUDE_COMMANDLINE := $(foreach exclude,$(_EXCLUDES),--exclude "$(exclude)")


# with dpkg-deb
# replace 4 spaces with TAB for below
deb: stage
    rm -fr $(PACKAGENAME)_$(PACKAGEVERSION)_$(ARCH).deb $(PACKAGEFOLDER)/control.tar.gz $(PACKAGEFOLDER)/data.tar.gz $(PACKAGEFOLDER)/tmp
    mkdir -p $(PACKAGEFOLDER)/Library/MobileSubstrate/DynamicLibraries/
    mkdir -p $(PACKAGEFOLDER)/DEBIAN
    cp $(OBJFOLDER)/$(TWEAK_NAME).dylib $(PACKAGEFOLDER)/Library/MobileSubstrate/DynamicLibraries/.
    cp $(CONTROLFILE) $(PACKAGEFOLDER)/DEBIAN/
    dpkg-deb -b $(PACKAGEFOLDER) $(PACKAGENAME)_$(PACKAGEVERSION)_$(ARCH).deb

# without dpkg-deb
# replace 4 spaces with TAB for below
deb2: stage
    mkdir -p $(PACKAGEFOLDER)/Library/MobileSubstrate/DynamicLibraries/
    mkdir -p $(PACKAGEFOLDER)/DEBIAN
    cp $(CONTROLFILE) $(PACKAGEFOLDER)/DEBIAN/
    rm -f $(PACKAGENAME)_$(PACKAGEVERSION)_$(ARCH).deb $(PACKAGEFOLDER)/control.tar.gz $(PACKAGEFOLDER)/data.tar.gz
    rm -f $(PACKAGEFOLDER)/tmp/*.gz
    mkdir -p $(PACKAGEFOLDER)/tmp
    echo "2.0" > $(PACKAGEFOLDER)/tmp/debian-binary
    cp $(OBJFOLDER)/$(TWEAK_NAME).dylib $(PACKAGEFOLDER)/Library/MobileSubstrate/DynamicLibraries/.
    cd $(PACKAGEFOLDER)/DEBIAN; tar -czf ../tmp/control.tar.gz ./
    cd $(PACKAGEFOLDER); tar -czf ./tmp/data.tar.gz $(_EXCLUDE_COMMANDLINE) ./
    cd $(PACKAGEFOLDER)/tmp; ar -rv ../../$(PACKAGENAME)_$(PACKAGEVERSION)_$(ARCH).deb ./debian-binary ./control.tar.gz ./data.tar.gz
    rm -fr $(PACKAGEFOLDER)/tmp/*.gz


For mobilesubstrate extension, download the iPhone headers from http://github.com/rpetrich/iphoneheaders/archives/master

and place the frameworks at top level (i.e. SpringBoard folder copy to /var/theos/include/SpringBoard).
libsubstrate.dylib is also needed in /var/theos/lib folder

Note: perl is needed for creating project folder and compiling mobilesubstrate extension, if you only develop app and command line tool, you could remove perl by using

apt-get remove perl


(14) This is how to combine Tweak and Settings Bundle in a project
/var/theos/bin/nic.pl MyTweak
and choose [5.] iphone/tweak
/var/theos/bin/nic.pl MyTweakSettings
and choose [3.] iphone/preference_bundle
mv mytweaksettings/*.mm mytweaksettings/Resources mytweaksettings/entry.plist mytweak/

Makefile (Tweak + Bundle) Select all

export THEOS=/var/theos
export GO_EASY_ON_ME=1
include $(THEOS)/makefiles/common.mk

TWEAK_NAME = MyTweak
#MyTweak_FILES = MyTweak.xm
MyTweak_FRAMEWORKS = UIKit

BUNDLE_NAME = MyTweakSettings
MyTweakSettings_FILES = MyTweakSettings.mm
MyTweakSettings_INSTALL_PATH = /System/Library/PreferenceBundles
MyTweakSettings_FRAMEWORKS = UIKit
MyTweakSettings_PRIVATE_FRAMEWORKS = Preferences

ADDITIONAL_CFLAGS = -I"$(SYSROOT)/usr/lib/gcc/arm-apple-darwin10/4.2.1/include"
ADDITIONAL_CCFLAGS = -I"$(SYSROOT)/usr/include/c++/4.2.1"
ADDITIONAL_CCFLAGS += -I"$(SYSROOT)/usr/include/c++/4.2.1/armv6-apple-darwin10"

include $(THEOS_MAKE_PATH)/tweak.mk
include $(THEOS_MAKE_PATH)/bundle.mk
include $(THEOS_MAKE_PATH)/aggregate.mk

# replace 4 spaces with TAB for below
internal-stage::
    $(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END)
    $(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/$(BUNDLE_NAME).plist$(ECHO_END)

# replace 4 spaces with TAB for below
after-stage::
    find $(THEOS_STAGING_DIR) -iname '*.plist' -exec plutil -convert binary1 {} \;
    $(FAKEROOT) chown -R 0:80 $(THEOS_STAGING_DIR)


(15) If you want to test the iOS5 Notification Center Widget
get it from http://github.com/WillFour20/WeeAppTest

git clone git://github.com/WillFour20/WeeAppTest.git

and modified with the following Makefile

Makefile (nc Tweak) Select all

export THEOS=/var/theos
SDKVERSION = 5.0
include $(THEOS)/makefiles/common.mk

BUNDLE_NAME = WeeAppTest
WeeAppTest_FILES = WeeAppTest.mm
WeeAppTest_INSTALL_PATH = /System/Library/WeeAppPlugins/
WeeAppTest_FRAMEWORKS = UIKit CoreGraphics
#WeeAppTest_PRIVATE_FRAMEWORKS = BulletinBoard

ADDITIONAL_CFLAGS = -I"$(SYSROOT)/usr/lib/gcc/arm-apple-darwin10/4.2.1/include"
ADDITIONAL_CCFLAGS = -I"$(SYSROOT)/usr/include/c++/4.2.1"
ADDITIONAL_CCFLAGS += -I"$(SYSROOT)/usr/include/c++/4.2.1/armv6-apple-darwin10"

include $(THEOS_MAKE_PATH)/bundle.mk

# replace 4 spaces with TAB for below
after-install::
    install.exec "killall -9 SpringBoard"


and make clean package install

(15) where is IOSurfaceAPI.h in Lion ?

Here
/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/IOSurface.framework/Headers/IOSurfaceAPI.h





iphone-gcc patched package for iPhone 5 / iPad 4 is here below
http://code.google.com/p/apiexplorer/downloads/list

7 comments:

iphone developer said...

i have window 7 in iphone
so will that coding able to work ?

Dustin L. Howett said...

You should not actually move the files from the settings project to the other project, that will just break things. Why not use aggregated toplevel subprojects? Put 'mytweaksettings' inside 'mytweak' and set SUBPROJECTS=mytweaksettings.

Don't take this advice *too* lightly, I am the author of Theos. :P

Xenophon Fenderson, the Carbon(d)ated said...

I just tried to follow these instructions, but the Perl install failed with APT returning a size-mismatch error on the p5-IO-Compress package:

Get:1 http://coredev.nl iphone/main p5-IO-Compress 2.048 [239kB]
Fetched 239kB in 2s (97.3kB/s)
Failed to fetch http://coredev.nl/cydia/dists/iphone/main/binary-iphoneos-arm/p5-IO-Compress-2.048.deb Size mismatch
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

Is there something wrong with at the source?

seoinheritx said...

Hey being a professional for iPhone Application Development i can simply say that its awesome article and you have great knowledge.

tang3w said...

Xenophon Fenderson, the Carbon(d)ated, How do you fix the problem of p5-IO-Compress size-mismatch error?

javacom said...

This is probably a download problem, just try again.

Safdar said...

Great post with helpful details. I like your idea.