Sunday, November 22, 2009

How to create local and remote ssh git repo in Mac OS X

(1) Install git for Mac OS X

mkdir ~/src
cd ~/src/
curl -O http://kernel.org/pub/software/scm/git/git-1.6.5.3.tar.bz2
tar -xjvf git-1.6.5.3.tar.bz2
cd git-1.6.5.3
./configure --prefix=/usr/local
make
sudo make install
git --version


(2) Create localrepo in local harddisk / SMB Share (assume already init as a repository)
init as a git repository

cd ~/myproject
git init
git add .
git rm -r --cache build     # ignore the build directory for iPhone project
git commit -m 'Initial commit'


git mkdir -p ~/git
git clone --bare ~/myproject ~/git/myproject.git
touch ~/git/myproject.git/git-daemon-export-ok


git mkdir -p /Volumes/Data/GIT
git clone --bare ~/myproject /Volumes/Data/GIT/myproject.git
touch /Volumes/Data/GIT/myproject.git/git-daemon-export-ok

push to localrepo

cd ~/myproject
git remote add localrepo ~/git/myproject.git
git push localrepo master
git log


(3) Suppose you have a project in ~/myproject
and the remote ssh server login is user@xxx.xxx.xxx.xxx
both client and server have git installed

(4) Create sshrepo in remote server over ssh

ssh user@xxx.xxx.xxx.xxx "mkdir -p /Volumes/HD/git/myproject.git; cd /Volumes/HD/git/myproject.git; git --bare init; touch git-daemon-export-ok"


check the location of remote git binary and the remote ssh login shell


ssh user@xxx.xxx.xxx.xxx "which git-upload-pack"
ssh user@xxx.xxx.xxx.xxx "echo \$PATH"


mine is /usr/local/bin/git-upload-pack


if the remote login shell does not include path of git, create ~/.bashrc in your remote ssh login shell


ssh user@xxx.xxx.xxx.xxx "echo 'export PATH=\${PATH}:/usr/local/bin' > ~/.bashrc"


push to sshrepo

cd ~/myproject
git remote add sshrepo ssh://user@xxx.xxx.xxx.xxx/Volumes/HD/git/myproject.git
git push sshrepo master
git log



Test git clone

cd ~
git clone ~/git/myproject.git workinglocal
cd workinglocal
git log


or


cd ~
git clone ssh://user@xxx.xxx.xxx.xxx/Volumes/HD/git/myproject.git workingremote
cd workingremote
git log


How to Branch

git branch -r                 # show branch in repo
git checkout -b todo origin/to-do-branch # checkout a new branch
git checkout master           # checkout the master branch

git checkout localrepo/master # checkout the master branch in localrepo
git checkout sshrepo/master   # checkout the master branch in sshrepo

git branch next               # create new branch
git add .
git commit -m 'commit nextbranch'
git push localrepo next

git branch -b cygwin
git branch -r
git add *
git commit -m 'commit cygwin branch'
git push origin cygwin


How to checkout a previous commit

git log # show log of previous commit
git log --format=oneline # show log of previous commit log hex digit
git checkout 838fbf2e9b050d2350694235bbf5e9a11fa7acea # commit log hexdigit
git checkout 838fbf2e9b050d2350694235bbf5e9a11fa7acea -- file1/to/restore file2/to/restore # checkout files to restore


How to push to github

git config --global user.name "javacom"
git config --global user.email "javacomhk@yahoo.com"
git remote rm origin
git remote add origin git@github.com:javacom/toolchain4.git
git push origin master









Sunday, October 4, 2009

How to compile mobilesubstrate extension in iPhone gcc for OS 3.0

(1) You need iphone gcc installed in your jailbroken iPhone / iPod Touch with firmware 3.0 or above

iPhone gcc is available in Cydia. To install it in you need to do these


# assume you have installed APT 0.6 Transitional and Aptitude and wget in Cydia, so that you can use the command apt-get
# if libgcc is broken in Cydia, you have to install it manually before iphone-gcc
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
# install iphone-gcc
apt-get install iphone-gcc


Moreover, you need these utilities as well


apt-get install make ldid zip unzip wget


for editor in iPhone you can use vim or nano

(2) You need the header files of toolchain and SDK 3.0, libsubstrate and classdump the SpringBoard and UIKit headers

The building of iPhone gcc in Linux and header files (updated for OS 3.0) is here in
http://www.saurik.com/id/4

The updated mobilesubtrate header files are here

The classdump procedure is here

But all these involved a lot of downloading and patching, so I put all the downloading/classdump/patching in one zipped tar file (sys30.tgz). You can download it (about 96M) here

(3) copy and untar the required headers and libraries (say copy to /var/mobile/sys30.tgz) and install it in iPhone / iPod Touch say

mkdir /var/toolchain/
cd /var/toolchain/
tar -xzvf /var/mobile/sys30.tgz


(4) Use this sample mobilesubstrate extension (ExampleHook.zip) and unzip it to test. You need to apt-get install mobilesubstrate in iPhone / iPod Touch first

http://apiexplorer.googlecode.com/files/ExampleHook.zip

apt-get install mobilesubstrate
wget http://apiexplorer.googlecode.com/files/ExampleHook.zip
unzip ExampleHook.zip
cd ExampleHook

make (to compile and codesign)
make install (to install), after install you need respring the device to test
make uninstall (to uninstall), after uninstall you need respring as well

respring utility is available from my cydia source http://cydia.iphone.org.hk/apt/

(5) You can also checkout a copy of the iphone backgrounder to test your iphone gcc and mobilesubstrate development environment
http://code.google.com/p/iphone-backgrounder/source/checkout

Install subversion before using svn in iPhone / iPod Touch

apt-get install subversion
svn checkout http://iphone-backgrounder.googlecode.com/svn/trunk/ iphone-backgrounder
cd iphone-backgrounder



I use this modified Makefile to compile iphone-backgrounder
MakefileSelect all

NAME = Backgrounder
APP_ID = jp.ashikase.backgrounder

# These paths must be changed to match the compilation environment
TOOLCHAIN = /var/toolchain/sys30/dump
SYS_PATH = /var/toolchain/sys30
MS_PATH = /var/toolchain/sys30/mobilesubstrate
INC_PATH = /var/toolchain/sys30/usr/include
LDID = /usr/bin/ldid

CXX = arm-apple-darwin9-g++
CXXFLAGS = -g0 -O2 -Wall -Werror -Wno-write-strings -include common.h -DAPP_ID=\"$(APP_ID)\"
LD = $(CXX)
LDFLAGS = -march=armv6 \
-mcpu=arm1176jzf-s \
-bind_at_load \
-multiply_defined suppress \
-framework CoreFoundation \
-framework Foundation \
-framework UIKit \
-framework GraphicsServices \
-framework CoreGraphics \
-F$(SYS_PATH)/System/Library/Frameworks \
-F$(SYS_PATH)/System/Library/PrivateFrameworks \
-L$(SYS_PATH)/usr/lib -lsubstrate \
-lobjc

INCLUDES = -I$(INC_PATH) -I$(MS_PATH) -I$(TOOLCHAIN) \
-I./Classes

SUBDIRS = . Classes

DIRLIST := $(SUBDIRS:%=%)
SRCS := $(foreach dir,$(DIRLIST), $(wildcard $(dir)/*.mm))
HDRS := $(foreach dir,$(DIRLIST), $(wildcard $(dir)/*.h))
OBJS := $(SRCS:.mm=.o)

all: $(NAME).dylib

config:
ln -snf $(TOOLCHAIN) $(SYS_PATH)

# Replace 'iphone' with the IP or hostname of your device
install: config $(NAME).dylib
ssh root@iphone rm -f /Library/MobileSubstrate/DynamicLibraries/$(NAME).dylib
scp $(NAME).dylib root@iphone:/Library/MobileSubstrate/DynamicLibraries/
ssh root@iphone restart

$(NAME).dylib: $(OBJS) $(HDRS)
$(LD) -dynamiclib $(LDFLAGS) $(OBJS) -init _$(NAME)Initialize -o $@
$(LDID) -S $@

%.o: %.mm
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@

clean:
rm -f $(OBJS) $(NAME).dylib


P.S. This is how to compile a standard c++ program in iPhone gcc
test.cppSelect all

arm-apple-darwin9-g++ -I"/var/toolchain/sys30/usr/include" -I"/var/toolchain/sys30/usr/include/c++/4.2.1" -I"/var/toolchain/sys30/usr/include/c++/4.2.1/armv6-apple-darwin9" -g0 -O2 -Wall -L"/var/toolchain/sys30/usr/lib" -march=armv6 -mcpu=arm1176jzf-s test.cpp -o test






Sunday, August 2, 2009

Compatible code for OS 2.2.1 and 3.0

Recently, the itts apple server has a number of changes and one of my favourite opensource app AppSales Mobile failed to get the sales data. It is now updated and thanks to the developer for the updating

http://github.com/omz/AppSales-Mobile/


However, the project was set to compile for SDK3.0, there are only a few changes that need to bring this app to be compatible to OS 2.2.1 and 3.0 at the same time.

Here are the steps involved

(1) Base SDK set to iPhone Device 3.0
(2) In Project Settings, iPhone OS Deployment Target set to iPhone OS 2.2.1
(3) Change the source code in RootViewController.m that have setFont or setImage methods, there are about 18 such changes to be done.


This is how to change the source code by adding respondsToSelector: test before using the deprecated method



change from


  [footer.titleLabel setFont:[UIFont systemFontOfSize:14.0]];


to


  if ( [footer respondsToSelector:@selector(setFont:)] ) {
    [footer setFont:[UIFont systemFontOfSize:14.0]];
  }
  else {
    [footer.titleLabel setFont:[UIFont systemFontOfSize:14.0]];
  }




change from

  cell.imageView.image = [UIImage imageNamed:@"Daily.png"];


to


  if ( [cell respondsToSelector:@selector(setImage:)] ) {
    cell.image = [UIImage imageNamed:@"Daily.png"];
  }
  else {
    cell.imageView.image = [UIImage imageNamed:@"Daily.png"];
  }


You may get warnings when build to actual 2.2.1 OS device, but this is normal. However, you cannot build to 2.2.1 Simulator.

The modified source is available here
http://code.google.com/p/apiexplorer/source/detail?r=20

Revision 20 is a modified source (as above) for version 2009/7

Revision 23 is the updated modification for version 2009/11/19

to checkout a revision

svn checkout -r 20 http://apiexplorer.googlecode.com/svn/branches/AppSalesMobile221 AppSalesMobile221r20
svn checkout -r 23 http://apiexplorer.googlecode.com/svn/branches/AppSalesMobile221 AppSalesMobile221r23



If you want to check out a previous version based on the commit hexdigit from the github repo, do this

git clone git://github.com/omz/AppSales-Mobile.git AppSales0731
cd AppSales0731
git checkout -b b0731 ff248e8e6c23386f867514c1c331a469b7d4cf45
git log






Saturday, August 1, 2009

javacom change name

I have been asked by Sun Microsystems to change my App Store name to others stating that Javacom is an Unauthorized use of Java Trademark.



Obviously, I don't have the ability to counter with their request. But I have a few words to say

First of all, my name in App Store is javacom not Javacom
Second, Java and Java applet are not supported by official iPhone App Store app or web app.
Third, I did not program in Java, I only drink a cup of java when I do programming.

May be I have to drink milk instead.... Coffee may not be good for me




Monday, July 27, 2009

Picture Icon in email signature for iPhone

How to add CSS signature to your iPhone ?

The previous hack was to change the Preferences Settings for jailbreaked iPhone. But I have a better approach for non-jailbreaked iPhone, and with custom picture email signature as well. It works for 2.x firmware.

This will be a new functionality for my app Touch Dial Emoji (version 2.0) in App Store.


See screenshots here

Sunday, July 12, 2009

How to build a single iPhone application support both 2.x and 3.0 at the same time

I asked Apple Technical Support on how to build an iPhone application that runs on iPhone OS 2.x and yet uses iPhone OS 3.0 features if they are available.

They replied with a solution called weak linking

What is weak linking as quoted from http://devworld.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html

When a symbol in a framework is defined as weakly linked, the symbol does not have to be present at runtime for a process to continue running. The static linker identifies a weakly linked symbol as such in any code module that references the symbol. The dynamic linker uses this same information at runtime to determine whether a process can continue running. If a weakly linked symbol is not present in the framework, the code module can continue to run as long as it does not reference the symbol. However, if the symbol is present, the code can use it normally.

Here's the basic steps:

1. Use the latest tools with the latest SDK.

2. In your project, set the IPHONEOS_DEPLOYMENT_TARGET build setting to the oldest OS you want to support (say iPhone OS 2.0). And use GCC 4.2




3. If you use frameworks that are not present on that older OS, set the frameworks to be weak imported. Do this using the Linked Libraries list in the General tab of the target info window.




if you use Makefile to build the app add this in linker flag
  LDFLAGS += -weak_framework MessageUI

and add this key in Info.plist

  <key>MinimumOSVersion</key>
  <string>2.0</string>



This is how to test whether framework is available or not


#import <MessageUI/MessageUI.h>
#include <dlfcn.h>

    if ( dlsym(RTLD_DEFAULT, "MFMailComposeErrorDomain") != NULL ) {
        NSLog(@"%@", @"MessageUI framework is available");
        NSLog(@"MFMailComposeErrorDomain = %@", MFMailComposeErrorDomain);
    } else {
        NSLog(@"%@", @"MessageUI framework is not available");
    }



4. For places where you use C-style imports that aren't present on older systems, check whether the import is present before using it.

5. If you use Objective-C methods that aren't present on older systems, use -respondsToSelector: to verify that the methods are present before calling them.


if ( [[UIApplication sharedApplication] respondsToSelector:@selector(canOpenURL:)] ) {
  if ( [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel:996-1010"]] ) {
    NSLog(@"%@", @"tel URL is supported");
  } else {
    NSLog(@"%@", @"tel URL is not supported");
  }
} else {
  NSLog(@"%@", @"-canOpenURL: not available");
}


6. If you use Objective-C classes that aren't present on older systems, you can't just use the class directly. For example:

obj = [[NSUndoManager alloc] init];

will cause your application to fail to launch on iPhone OS 2.x, even if you weak link to the framework. Rather, you have to do the following:


NSUndoManager undoManager;
Class cls;
cls = NSClassFromString(@"NSUndoManager");
  if (cls != nil) {
    undoManager = [[[cls alloc] init] autorelease];
    NSLog(@"%@", @"NSUndoManager is available");

    // This tests whether we have access to NSUndoManager's selectors.

    [undoManager beginUndoGrouping];
    [undoManager endUndoGrouping];
  } else {
    NSLog(@"%@", @"NSUndoManager not available");
  }
  undoManager = nil;


7. Test, test, test!

Updated:
There is sample source code for the Mail Composer in Developer site
http://developer.apple.com/iphone/library/samplecode/MailComposer/index.html



Sunday, July 5, 2009

How to compile command line utility for iPhone using XCode gcc

hello.c

echo 'main() { printf("Hello, world!\n"); }' > hello.c


compile hello.c

/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.0 -arch armv6 -mthumb -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.sdk -o hello hello.c


compile with framework

/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.0 -arch armv6 -mthumb -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.sdk -framework Foundation -framework CoreFoundation -lobjc -std=c99 main.m -o main


codesign in Mac, if you have developer or self-signed certificate (can't codesign it when in ssh session)

export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate; codesign -f -s "iPhone Developer" hello


or you can codesign in iPhone, that is, send the binary to iPhone and then fake codesign it

ldid -S hello



This is how to use as (assembler) to compile hello.s to ARM thumb binary
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/as -arch armv6 hello.s -o hello


# GAS filename : hello.s
# use as to compile
# /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/as -arch armv6 hello.s -o hello
# use otool to disassemble
# otool -tv hello

  .globl _main
  .code 16
  .thumb_func _main
_main:
  push {r7, lr}
  add r7, sp, #0
  add r3, pc
  mov ip, r3
  mov r3, ip
  mov r0, r3
  pop {r7, pc}


.
.
.