To compile Lua for use on iPhone and iPad, I’ve grabbed the original source code for 5.1.4, and I have grabbed build_for_iphoneos.sh shell script by Christopher Stawarz. Both were slightly modified since Lua does not use autoconf, and build_for_iphoneos.sh is slightly dated. Read more to see what did I do.
You can read the full description with full copies of the files that need to be changed, or you can review diffs on the bottom of the post.
Full description
In “build_for_iphoneos.sh” I had to remove use of configure. I added a call to “make”. I’ve exported “prefix” so I can use it in modified Lua’s Makefile. Additionally, the script presumes older iOS SDKs will be shipped in newer Xcode releases, which isn’t the case for quite a while now; instead one needs to build with the latest SDK and specify that an older iPhone is a target.
Here’s the modified script:
#!/bin/bash ################################################################################ # # Copyright (c) 2008-2009 Christopher J. Stawarz # Modifications (c) 2011 Ivan Vucica # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation files # (the "Software"), to deal in the Software without restriction, # including without limitation the rights to use, copy, modify, merge, # publish, distribute, sublicense, and/or sell copies of the Software, # and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # ################################################################################ # Disallow undefined variables set -u default_gcc_version=4.2 default_iphoneos_version=3.1.2 default_macos_version=10.5 current_iphone_sdk=4.2 GCC_VERSION="${GCC_VERSION:-$default_gcc_version}" export IPHONEOS_SDK="${IPHONEOS_DEPLOYMENT_TARGET:-$current_iphone_sdk}" export IPHONEOS_DEPLOYMENT_TARGET="${IPHONEOS_DEPLOYMENT_TARGET:-$default_iphoneos_version}" export MACOSX_DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET:-$default_macos_version}" usage () { cat >&2 << EOF Usage: ${0##*/} [-ht] [-p prefix] target [configure_args] -h Print help message -p Installation prefix (default: \$HOME/Developer/Platforms/...) -t Use 16-bit Thumb instruction set (instead of 32-bit ARM) The target must be "device" or "simulator". Any additional arguments are passed to configure. The following environment variables affect the build process: GCC_VERSION (default: $default_gcc_version) IPHONEOS_DEPLOYMENT_TARGET (default: $default_iphoneos_version) MACOSX_DEPLOYMENT_TARGET (default: $default_macos_version) EOF } while getopts ":hp:t" opt; do case $opt in h ) usage ; exit 0 ;; p ) prefix="$OPTARG" ;; t ) thumb_opt=thumb ;; \? ) usage ; exit 2 ;; esac done shift $(( $OPTIND - 1 )) if (( $# < 1 )); then usage exit 2 fi target=$1 shift case $target in device ) arch=armv6 platform=iPhoneOS extra_cflags="-m${thumb_opt:-no-thumb} -mthumb-interwork" ;; simulator ) arch=i386 platform=iPhoneSimulator extra_cflags="-D__IPHONE_OS_VERSION_MIN_REQUIRED=${IPHONEOS_DEPLOYMENT_TARGET%%.*}0000" ;; * ) usage exit 2 esac platform_dir="/Developer/Platforms/${platform}.platform/Developer" platform_bin_dir="${platform_dir}/usr/bin" platform_sdk_dir="${platform_dir}/SDKs/${platform}${IPHONEOS_SDK}.sdk" prefix="${prefix:-${HOME}${platform_sdk_dir}}" export CC="${platform_bin_dir}/gcc-${GCC_VERSION}" export CFLAGS="-arch ${arch} -pipe -Os -gdwarf-2 -isysroot ${platform_sdk_dir} ${extra_cflags}" export LDFLAGS="-arch ${arch} -isysroot ${platform_sdk_dir}" export CXX="${platform_bin_dir}/g++-${GCC_VERSION}" export CXXFLAGS="${CFLAGS}" export CPP="/Developer/usr/bin/cpp-${GCC_VERSION}" export CXXCPP="${CPP}" #./configure \ # --prefix="${prefix}" \ # --host="${arch}-apple-darwin" \ # --disable-shared \ # --enable-static \ # "$@" || exit export prefix make "$@" || exit make install "$@" || exit cat >&2 << EOF Build succeeded! Files were installed in $prefix EOF
I’ve called this modified script “build_for_iphoneos_noconfigure.sh”, and just like the original one, I’ve placed it in my path for easier access at a later time.
Next, we need to make slight adaptations to the Makefile in “src/” subdirectory of lua-5.1.4. Primarily, we need to introduce use of LDFLAGS in addition to MYLDFLAGS in a few spots, since they’re set by “build_for_iphoneos_noconfigure.sh”. We need to remove setting of CC and CFLAGS, since they will also be set by the shell script.
# makefile for building Lua # see ../INSTALL for installation instructions # see ../Makefile and luaconf.h for further customization # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= # Your platform. See PLATS for possible values. PLAT= none #CC= gcc #CFLAGS= -O2 -Wall $(MYCFLAGS) AR= ar rcu RANLIB= ranlib RM= rm -f LIBS= -lm $(MYLIBS) MYCFLAGS= MYLDFLAGS= MYLIBS= # == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris LUA_A= liblua.a CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ lundump.o lvm.o lzio.o LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ lstrlib.o loadlib.o linit.o LUA_T= lua LUA_O= lua.o LUAC_T= luac LUAC_O= luac.o print.o ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) ALL_A= $(LUA_A) default: $(PLAT) all: $(ALL_T) o: $(ALL_O) a: $(ALL_A) $(LUA_A): $(CORE_O) $(LIB_O) $(AR) $@ $? $(RANLIB) $@ $(LUA_T): $(LUA_O) $(LUA_A) $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) $(LDFLAGS) $(LUAC_T): $(LUAC_O) $(LUA_A) $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) $(LDFLAGS) clean: $(RM) $(ALL_T) $(ALL_O) depend: @$(CC) $(CFLAGS) -MM l*.c print.c echo: @echo "PLAT = $(PLAT)" @echo "CC = $(CC)" @echo "CFLAGS = $(CFLAGS)" @echo "AR = $(AR)" @echo "RANLIB = $(RANLIB)" @echo "RM = $(RM)" @echo "MYCFLAGS = $(MYCFLAGS)" @echo "MYLDFLAGS = $(MYLDFLAGS)" @echo "MYLIBS = $(MYLIBS)" # convenience targets for popular platforms none: @echo "Please choose a platform:" @echo " $(PLATS)" aix: $(MAKE) all CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall" ansi: $(MAKE) all MYCFLAGS=-DLUA_ANSI bsd: $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" freebsd: $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline" generic: $(MAKE) all MYCFLAGS= linux: $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" macosx: $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline" # use this on Mac OS X 10.3- # $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX mingw: $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe $(MAKE) "LUAC_T=luac.exe" luac.exe posix: $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX solaris: $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" # list targets that do not create files (but not all makes understand .PHONY) .PHONY: all $(PLATS) default o a clean depend echo none # DO NOT DELETE lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \ lstate.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h \ lundump.h lvm.h lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ ltable.h ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \ llex.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ lfunc.h lstring.h lgc.h ltable.h lvm.h ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h \ ltable.h lundump.h lvm.h ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ lzio.h lmem.h lundump.h lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \ lstate.h ltm.h lzio.h lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \ lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ ltm.h lzio.h lmem.h ldo.h loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ lfunc.h lstring.h lgc.h ltable.h lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ ltm.h lzio.h lstring.h lgc.h lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ ltm.h lzio.h lmem.h ldo.h lgc.h ltable.h ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ lmem.h lstring.h lgc.h ltable.h lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \ lstate.h ltm.h lzio.h lmem.h lfunc.h lopcodes.h lstring.h lgc.h \ lundump.h lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ lzio.h print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ ltm.h lzio.h lmem.h lopcodes.h lundump.h # (end of Makefile)
Finally, you need to introduce a slight change to the Makefile in root of Lua’s distribution. INSTALL_TOP needs to be a replica of “prefix” environment variable since it’s set by the shell script.
Here’s just the excerpt of the top of the Makefile. I think you’ll easily notice what’s
# makefile for installing Lua # see INSTALL for installation instructions # see src/Makefile and src/luaconf.h for further customization # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= # Your platform. See PLATS for possible values. PLAT= none # Where to install. The installation starts in the src and doc directories, # so take care if INSTALL_TOP is not an absolute path. INSTALL_TOP= ${prefix} INSTALL_BIN= $(INSTALL_TOP)/bin INSTALL_INC= $(INSTALL_TOP)/include INSTALL_LIB= $(INSTALL_TOP)/lib INSTALL_MAN= $(INSTALL_TOP)/man/man1 ###### -- continues below --
That’s it. Now you can compile Lua for platform “generic” (trying to compile for “macosx” pulls in readline which isn’t available on iPhone):
build_for_iphoneos_noconfigure.sh device generic
Output should end with:
Build succeeded! Files were installed in /Users/ivucica/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.2.sdk
Excerpt from documentation for “build_for_iphoneos.sh”, which explains how to set up your Xcode project:
By default, the script will install files in a subdirectory of $HOME/Developer/Platforms that mirrors the layout of /Developer/Platforms. For example, the installation prefix for a device build defaults to $HOME/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.1.sdk. The advantage of this is that you can make Xcode aware of the installed files for both the simulator and the device by adding the following under “All Configurations” in your project settings:
Header Search Paths: $(HOME)/$(SDK_DIR)/include
Library Search Paths: $(HOME)/$(SDK_DIR)/lib
Of course, you can move these things into a better place, or you can attempt to design an SDK, similar to what I’ve done when adding iPhone support to libapril and friends.
Just the diffs
Using Mercurial I quickly made the following diff for lua-5.1.4, if you’re interested only in diff on Makefiles:
diff -r 130652fce1b4 Makefile --- a/Makefile Fri Mar 04 14:13:36 2011 +0100 +++ b/Makefile Fri Mar 04 14:13:56 2011 +0100 @@ -9,7 +9,7 @@ # Where to install. The installation starts in the src and doc directories, # so take care if INSTALL_TOP is not an absolute path. -INSTALL_TOP= /usr/local +INSTALL_TOP= ${prefix} INSTALL_BIN= $(INSTALL_TOP)/bin INSTALL_INC= $(INSTALL_TOP)/include INSTALL_LIB= $(INSTALL_TOP)/lib diff -r 130652fce1b4 src/Makefile --- a/src/Makefile Fri Mar 04 14:13:36 2011 +0100 +++ b/src/Makefile Fri Mar 04 14:13:56 2011 +0100 @@ -7,8 +7,8 @@ # Your platform. See PLATS for possible values. PLAT= none -CC= gcc -CFLAGS= -O2 -Wall $(MYCFLAGS) +#CC= gcc +#CFLAGS= -O2 -Wall $(MYCFLAGS) AR= ar rcu RANLIB= ranlib RM= rm -f @@ -52,10 +52,10 @@ $(RANLIB) $@ $(LUA_T): $(LUA_O) $(LUA_A) - $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) + $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) $(LDFLAGS) $(LUAC_T): $(LUAC_O) $(LUA_A) - $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) + $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) $(LDFLAGS) clean: $(RM) $(ALL_T) $(ALL_O)
And diff for the build_for_iphoneos.sh:
--- build_for_iphoneos.sh 2011-03-04 12:38:06.000000000 +0100 +++ build_for_iphoneos_noconfigure.sh 2011-03-04 13:48:05.000000000 +0100 @@ -36,7 +36,10 @@ default_iphoneos_version=3.1.2 default_macos_version=10.5 +current_iphone_sdk=4.2 + GCC_VERSION="${GCC_VERSION:-$default_gcc_version}" +export IPHONEOS_SDK="${IPHONEOS_DEPLOYMENT_TARGET:-$current_iphone_sdk}" export IPHONEOS_DEPLOYMENT_TARGET="${IPHONEOS_DEPLOYMENT_TARGET:-$default_iphoneos_version}" export MACOSX_DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET:-$default_macos_version}" @@ -103,7 +106,7 @@ platform_dir="/Developer/Platforms/${platform}.platform/Developer" platform_bin_dir="${platform_dir}/usr/bin" -platform_sdk_dir="${platform_dir}/SDKs/${platform}${IPHONEOS_DEPLOYMENT_TARGET}.sdk" +platform_sdk_dir="${platform_dir}/SDKs/${platform}${IPHONEOS_SDK}.sdk" prefix="${prefix:-${HOME}${platform_sdk_dir}}" export CC="${platform_bin_dir}/gcc-${GCC_VERSION}" @@ -115,14 +118,15 @@ export CXXCPP="${CPP}" -./configure \ - --prefix="${prefix}" \ - --host="${arch}-apple-darwin" \ - --disable-shared \ - --enable-static \ - "$@" || exit - -make install || exit +#./configure \ +# --prefix="${prefix}" \ +# --host="${arch}-apple-darwin" \ +# --disable-shared \ +# --enable-static \ +# "$@" || exit +export prefix +make "$@" || exit +make install "$@" || exit cat >&2 << EOF
–
via blog.vucica.net