iPhone - Why can the compiler not find some includes when building for ARM architecture?
I am trying to make use of a C library in an iPhone project. I am very green with iPhone development. My Library
I have been battling for days now to try and get this library build into a static library that I can use for both the simulator (i386) and ARM7.
Using the the library's include configuration and makefile I can build the library without issue. However if I edit the makefile to try and build this same library but target the armv7 architecture I get many errors. The errors seem to be reporting that some header files cannot be located.
So does the compiler attempt to look in different places for header files depending on the target architecture?
This is the make file that I have edited to attempt to build for the armv7:
# $Id: Makefile.in 62 2005-03-09 21:11:53Z gyunaev $
CC = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-gcc-4.2.1
CFLAGS = -Wall -DIN_BUILDING_LIBIRC -O3 -DENABLE_THREADS -D_REENTRANT
AR=ar cr
RANLIB=ranlib
INCLUDES=-I../include
OBJS = libircclient.o
all: lib
lib: libircclient.a
install: lib
-mkdir /usr/local/include
-mkdir /usr/local/lib
cp ../include/libircclient.h /usr/local/include/libircclient.h
cp ../include/libirc_errors.h /usr/local/include/libirc_errors.h
cp ../include/libirc_events.h /usr/local/include/libirc_events.h
cp libircclient.a /usr/local/include/lib/libircclient.a
$(OBJS): utils.c dcc.c errors.c portable.c sockets.c colors.c
libircclient.a: $(OBJS)
$(AR) libircclient.a $(OBJS)
$(RANLIB) libircclient.a
clean:
rm -f libircclient.a $(OBJS)
distclean: clean
-rm -f Makefile
.c.o:
@echo "Compiling $<"
@$(CC) $(CFLAGS) $(INCLUDE开发者_如何转开发S) -c -o $@ $<
Here is a sample of the compilation errors I am experiencing:
Compiling libircclient.c
In file included from /usr/include/sys/_types.h:33,
from /usr/include/_types.h:27,
from /usr/include/stdio.h:64,
from portable.c:18,
from libircclient.c:15:
/usr/include/machine/_types.h:36:24: error: arm/_types.h: No such file or directory
In file included from /usr/include/_types.h:27,
from /usr/include/stdio.h:64,
from portable.c:18,
from libircclient.c:15:
/usr/include/sys/_types.h:94: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__darwin_blkcnt_t’
/usr/include/sys/_types.h:95: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__darwin_blksize_t’
/usr/include/sys/_types.h:96: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__darwin_dev_t’
Am I going about this all wrong? Is editing the makefile dumb? :) How do you unix ninjas handle this situation? Some research has lead me to believe that I need to create a universal library...
Thanks!
The problem is that the include file in /usr/include are for Mac OS X, not for the iPhone/iPad. If you want to get things to work you will have to add (at least) the flags that Kay mentioned in her comment...
A much easier way to go about this is to use XCode. Just create a new project (choose the Cocoa Touch Static Library) and add the source files. According to the Makefile you will need to add: utils.c dcc.c errors.c portable.c sockets.c colors.c
Hope this helps.
You might also check out IRCClient which is a Objective-C wrapper for the library you are using. No point reinventing the wheel!
ADDITIONAL INFORMATION 5/8/11
Turns out the Objective-C wrapper is aimed at Mac OS X not iOS
Here's what you need to do to get this to compile:
Get the sources fresh:
svn co https://libircclient.svn.sourceforge.net/svnroot/libircclient libircclient
Change into the libircclient/trunk/libircclient/src directory and run
./configure
Note: this is a slightly dirty trick. This is really configuring for Mac OS X but most of the times things are similar enough for this to work. This generates a file called config.h in include.
Fire up XCode and choose to create a new Cocoa Touch static library. When prompted create a new directory libircclient/trunk/libircclient/iOS and save the new project there.
Add the file libircclient.c from libircclient/trunk/libircclient/src to the project. It turns out that this file includes all the other C files.
Open your project settings and add ../../include to you search header path.
Build and enjoy!
As Kay indicated in a comment, if you are trying to build from the command line (or via Make), you must specify the -isysroot $(SDKROOT)
flag in order to get the correct headers (otherwise you pick up the host Mac OS X headers, which do not necessarily support ARM).
The easiest thing is to build with XCode, or find a version of the library designed to build for iOS, but if you must use an existing Make-driven build system, you can adapt it to build for iOS by setting:
TARGETSDK = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.2.sdk
CC = xcrun -sdk $(TARGETSDK) gcc
CFLAGS = -arch armv7 -isysroot $(TARGETSDK) ...
You will want to use similar xcrun
commands for other tools used in your build.
I've had some success adding the following to my .bash_profile:
# OS SDK PATHS
IPHONE_SDK=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk
IPHONESIM_SDK=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk
MACOSX_SDK=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk
export IPHONE_SDK
export IPHONESIM_SDK
export MACOS_SDK
C_INCLUDE_PATH=$HOME/local/include:$IPHONE_SDK/usr/include:$IPHONESIM_SDK/usr/include
CPLUS_INCLUDE_PATH=$C_INCLUDE_PATH
export C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH
This gives adds all of the architecture-dependent header files to your include folder. After that, I was able to compile C++ libraries without any other modifications.
With Xcode 4.6, things have changed a bit. Here is the script I am using the convert some C code to ASM so that one can view the output of clang for armv7 (thumb2).
#!/bin/bash
DEVROOT=/Applications/Xcode.app/Contents/Developer
SDK=$DEVROOT/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk
CLANG=$DEVROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
$CLANG \
-x c -arch armv7 \
-std=gnu99 \
-Os \
-isysroot $SDK \
-S code.c -o code.s
Take a look at the generated .s to see the ARM ASM output.
精彩评论