= Xcode3 Project Setup
after creating the actual XCode Project:
# install [[http://git-scm.com/|git]] e.g. from http://code.google.com/p/git-osx-installer/
# get [[http://www.doxygen.org/|Doxygen]], e.g. [[http://www.stack.nl/~dimitri/doxygen/download.html|the DMG]]
# get [[http://uncrustify.sourceforge.net/|uncrustify]] e.g. bundled with from [[http://sourceforge.net/projects/universalindent/files/|UniversalIndentGUI]]
== App ID
# [[http://developer.apple.com/iphone/manage/overview/index.action|Apple Developer Program Portal]]
Hint: insert one wildcard to allow multiple packages (App, Test, etc.) - so be both specific (domain, project) and liberal at the same time.
The range spanned by the App ID can be signed with **one** single Provisioning Profile, so I suggest to be specific up to a project level but allow multiple Apps to be able to try things out in small experimental Apps.
== Provisioning Profile
# [[http://developer.apple.com/iphone/manage/overview/index.action|Apple Developer Program Portal]]
# download it and drop it into the XCode Organizer
# Project -> Edit Project Settings -> Build -> **each configuration separately** -> Code Signing Identity
== .gitignore
*~
build/
.~lock*
*.mode1v3
# maybe version Custom Executable Settings?
# http://cocoawithlove.com/2009/12/sample-iphone-application-with-
*.pbxuser
== Makefile
copy alongside the *.xcodeproj and edit top 10 Lines:
#!/usr/bin/make
# Make help: http://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets
APP :=
APP_TARGET :=
PROVISION :=
DEPLOY_DIR :=
INFO_PLIST :=
TEST_TARGET := LogicTests
COREDATA_MODEL := $(APP).xcdatamodel
BUILD_DIR := ./build/
VERSION := $(shell grep -A1 CFBundleVersion $(INFO_PLIST) | tail -n 1 | egrep -oe ">([^<]+)" | cut -c 2-)
DOXYGEN_DIR := $(BUILD_DIR)/doxygen/
# non-standard tools. Set if unset in environment
DOXYGEN ?= $(HOME)/Applications/Doxygen.app/Contents/Resources/doxygen# http://www.stack.nl/~dimitri/doxygen/download.html#latestsrc
DOT_PATH ?= $(dir $(DOXYGEN))# http://www.stack.nl/~dimitri/doxygen/download.html#latestsrc
GIT ?= git # http://code.google.com/p/git-osx-installer/
OPTIPNG ?= optipng # http://optipng.darwinports.com/
UNCRUSTIFY ?= $(HOME)/Applications/UniversalIndentGUI/indenters/uncrustify # http://universalindent.sourceforge.net/index.php
UNCRUSTIFY_OPTS := -l OC --replace --no-backup -c uncrustify.cfg
XCODEBUILD := xcodebuild
AGVTOOL := agvtool
ZIP ?= zip
.PHONY: tests pretty clean
defaultTarget: tests
SOURCES := *.pch Classes/*.h Classes/*.m Classes/*/*.h Classes/*/*.m Tests/*.h Tests/*.m Tests/*/*.m
################################################################
##
## help
##
## explain this Makefile's major targets
##
help:
@egrep -A1 -e "^[a-zA-Z0-9]+:|^##" Makefile
################################################################
##
## toolversions
##
## print all used tools' versions
##
toolversions:
@echo "----------------------------------------------------------"
make --version
@echo "----------------------------------------------------------"
-$(XCODEBUILD) -version
@echo "----------------------------------------------------------"
-$(GIT) --version
@echo "----------------------------------------------------------"
-$(DOXYGEN) --version
@echo "----------------------------------------------------------"
-$(DOT_PATH)/dot -V
@echo "----------------------------------------------------------"
-$(UNCRUSTIFY) --version
@echo "----------------------------------------------------------"
-$(OPTIPNG) --version
@echo "----------------------------------------------------------"
-$(ZIP) --version
################################################################
##
## all
##
## Build anything
##
all: pretty debug release docset
################################################################
##
## debug
##
## $(XCODEBUILD) the Debug / $(DEVICE_SDK) configuration
##
debug: $(SOURCES)
$(XCODEBUILD) -project $(APP).xcodeproj -target $(APP_TARGET) -configuration Debug -sdk $(DEVICE_SDK)
################################################################
##
## release
##
## $(XCODEBUILD) the Release / $(DEVICE_SDK) configuration
##
release: $(SOURCES)
$(XCODEBUILD) -project $(APP).xcodeproj -target $(APP_TARGET) -configuration Release -sdk $(DEVICE_SDK)
################################################################
##
## alltargets
##
## $(XCODEBUILD) the Debug / $(DEVICE_SDK) configuration
##
alltargets: $(SOURCES)
$(XCODEBUILD) -project $(APP).xcodeproj -alltargets -configuration Debug -sdk $(DEVICE_SDK)
################################################################
##
## tests
##
## $(XCODEBUILD) & run the unit (logic) tests
##
tests: $(SOURCES)
$(XCODEBUILD) -project $(APP).xcodeproj -target $(TEST_TARGET) -configuration Debug -sdk $(SIMULATOR_SDK)
################################################################
##
## clean
##
## remove built artifacts
##
clean:
rm -r $(BUILD_DIR)
mkdir $(BUILD_DIR)
################################################################
##
## pretty
##
## indent source code (pretty print)
##
pretty: uncrustify
uncrustify: $(SOURCES)
@${UNCRUSTIFY} ${UNCRUSTIFY_OPTS} `ls $? 2> /dev/null`
optipng: *.png Images/*.png
$(OPTIPNG) -o9 $?
################################################################
##
## doc
##
## build doxygen documentation. Inject version?
##
doc: $(DOXYGEN_DIR)/html/index.html
$(DOXYGEN_DIR)/html/index.html: $(BUILD_DIR)/doxygen.generated $(SOURCES)
$(DOXYGEN) $<
open $@
@echo ===============================================================================
@echo === doxygen warnings:
# @cat $(BUILD_DIR)/doxygen/warnings.log
$(BUILD_DIR)/doxygen.generated: doxygen.config $(INFO_PLIST)
-mkdir -p $(DOXYGEN_DIR)
cp $< $@
sed -i '' -e "s|DOT_PATH *=.*|DOT_PATH = $(DOT_PATH)|g" $@
sed -i '' -e "s/PROJECT_NUMBER *=.*/PROJECT_NUMBER = $(VERSION)/g" $@
sed -i '' -e "s|OUTPUT_DIRECTORY *=.*|OUTPUT_DIRECTORY = $(DOXYGEN_DIR)|g" $@
################################################################
##
## docset
##
## build + integrate doxygen docs into XCode.
## http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
##
docset: $(DOXYGEN_DIR)/html/index.html
make -C $(dir $<) install
################################################################
##
## ipa
##
## build, test, tag, package into 2 ipa files ready for testing.
##
ipa: debug release tests tag \
$(BUILD_DIR)/ipa/Debug/$(APP_TARGET).ipa \
$(BUILD_DIR)/ipa/Release/$(APP_TARGET).ipa
$(BUILD_DIR)/ipa/Debug/$(APP_TARGET).ipa: $(BUILD_DIR)/Debug-iphoneos/$(APP_TARGET).app
-rm -r $(dir $@)
mkdir -p $(dir $@)/Payload
cp -rp $<.dSYM $(dir $@)
cp -rp $< $(dir $@)/Payload/
cd $(dir $@) ; \
$(ZIP) -qrp9 $(APP_TARGET).ipa Payload/$(APP_TARGET).app
rm -r $(dir $@)/Payload
ls $@
$(BUILD_DIR)/ipa/Release/$(APP_TARGET).ipa: $(BUILD_DIR)/Release-iphoneos/$(APP_TARGET).app
-rm -r $(dir $@)
mkdir -p $(dir $@)/Payload
cp -rp $<.dSYM $(dir $@)
cp -rp $< $(dir $@)/Payload/
cd $(dir $@) ; \
$(ZIP) -qrp9 $(APP_TARGET).ipa Payload/$(APP_TARGET).app
rm -r $(dir $@)/Payload
ls $@
################################################################
##
## dropbox
##
## build IPAs & doc and copy to dropbox
##
dropbox: ipa doc
-rm -r $(DEPLOY_DIR)/v$(VERSION) 2> /dev/null
-rm -r $(DEPLOY_DIR)/ipa 2> /dev/null
cp -rp $(BUILD_DIR)/ipa $(DEPLOY_DIR)
cp -p $(PROVISION) $(DEPLOY_DIR)/ipa
cp -rp $(DOXYGEN_DIR)/* $(DEPLOY_DIR)/ipa
mv $(DEPLOY_DIR)/ipa $(DEPLOY_DIR)/v$(VERSION)
ls -dl $(DEPLOY_DIR)/v$(VERSION)/*/$(APP_TARGET).*
# ###############################################################
# internal use only:
# - fail if there's uncommitted changes waiting
# - fail if unable to set the Info.plist's version's tag
tag:
ifeq (2, $(strip $(shell $(GIT) status | wc -l)))
$(AGVTOOL) next-version -all
# sed -i '' -e "s/PROJECT_NUMBER *=.*/PROJECT_NUMBER = $(VERSION)/g" doxygen.config
$(GIT) commit -a -m "agvtool next-version: v$(VERSION)"
$(GIT) tag -a -m "agvtool next-version" v$(VERSION)
else
$(GIT) status # assumed to return exit code 1 in any case.
exit 1 # just to be 100% sure to exit in error...
endif
== Doxygen
copy and edit the ''doxygen.config'':
# PROJECT_NAME
# DOCSET_FEEDNAME
# DOCSET_BUNDLE_ID
== Apple Generic Versioning
or agvtool: http://chanson.livejournal.com/125568.html
# Project -> Edit Project Settings -> Versioning System = "Apple Generic"
# Project -> Edit Project Settings -> Current Project Version = "1"
# Info.plist -> CFBundleVersion = "1"
# Info.plist -> CFBundleShortVersionString = "0.0.1alpha"
== Unit Tests
http://cocoawithlove.com/2009/12/sample-iphone-application-with-complete.html
# Project -> New Target... -> Unit Test Bundle -> "LogicTests"
# Targets -> LogicTests -> Get Info -> General -> Direct Dependencies -> add App "main" target
# evtl. add OCMock + Project -> Edit Project Settings -> Build -> Search Paths -> Header Search Paths -> "Classes" (non-recursive)
# Project -> Edit Project Settings -> Build -> GCC_PREFIX_HEADER -> MyProject_Prefix.pch
# Debugging them: Project -> New Custom Executable -> Name:"LogicTestsDebug", Path:"Developer/usr/bin/otest" ("Relative to Current SDK")
# Executable -> Arguments -> Argument
-SenTest Self
$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/LogicTests.octest
# Executable -> Arguments -> Variables
DYLD_ROOT_PATH = $(SDKROOT)
IPHONE_SIMULATOR_ROOT = $(SDKROOT)
DYLD_LIBRARY_PATH = $(BUILT_PRODUCTS_DIR):$(SDKROOT)
DYLD_FRAMEWORK_PATH = $(BUILT_PRODUCTS_DIR):$(SDKROOT)
CFFIXED_USER_HOME = $(HOME)/Library/Application Support/iPhone Simulator/User
DYLD_NEW_LOCAL_SHARED_REGIONS = YES
DYLD_NO_FIX_PREBINDING = YES
DYLD_FORCE_FLAT_NAMESPACE = YES
**Caution**: the settings 6. + 7. go into the per-user username.pbxuser
== Integration Tests
todo, see http://cocoawithlove.com/2009/12/sample-iphone-application-with-complete.html
{{tag> XCode iPhone Makefile Doxygen agvtool Unit Test OCMock SenTest git}}