Archive Info

You are currently browsing the PolyMicro Systems weblog archives for November, 2007.

Unused software rots (or tracking down header errors in Xcode 3.0)

I was trying to revive an old program fslogger from Amit Singh’s MacOSX Internals and compile it with Xcode 3.0 when I discovered it would not compile. Sigh… If you don’t keep on top of development changes your software will rot.

I assumed at first it was because I was using the default settings on a new command line tool. I tired changing the target SDK for the project to 10.4 and 10.3.9 to no avail so I started looking at the build results a bit more closely.

First, to simplify the problem I stripped down the source code to a bare minimum command line project that looked like this.


// fslogger.c

#include ‹stdio.h›

int main(int argc, char **argv) {
printf(”Hello world”);
}

Just for a sanity check on a basic project. This compiled fine so I added in the needed libraries.


// fslogger.c

#include ‹stdio.h›
#include ‹string.h›
#include ‹fcntl.h›
#include ‹stdlib.h›
#include ‹unistd.h›
#include ‹sys/ioctl.h›
#include ‹sys/types.h›
#include ‹sys/sysctl.h›
#include ‹sys/fsevents.h›
#include ‹pwd.h›
#include ‹grp.h›

int main(int argc, char **argv) {
printf(”Hello world”);
}

This is where I immediately ran into the problem. The build was returning:


CompileC build/fslogger.build/Release/fslogger.build/Objects-normal/i386/main.o /Users/davec/fslogger/main.c normal i386 c com.apple.compilers.gcc.4_0
cd /Users/davec/fslogger
/Developer/usr/bin/gcc-4.0 -x c -arch i386 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -Wreturn-type -Wunused-variable -fmessage-length=0 -fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -iquote /Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-generated-files.hmap -I/Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-own-target-headers.hmap -I/Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-all-target-headers.hmap -iquote /Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-project-headers.hmap -F/Users/davec/fslogger/build/Release -I/Users/davec/fslogger/build/Release/include -I/Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/DerivedSources -isysroot /Developer/SDKs/MacOSX10.5.sdk -c /Users/davec/fslogger/main.c -o /Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/Objects-normal/i386/main.o
/Users/davec/fslogger/main.c:11:26: error: sys/fsevents.h: No such file or directory

Ah ha, I forgot to set the header search path! Or so I thought. I added in


HEADER_SEARCH_PATHS = ~/Sources/xnu/bsd/sys

to the build options for the project which is where I had my xnu sources where fsevents.h was located and tried again. This time I got a different error:


CompileC build/fslogger.build/Release/fslogger.build/Objects-normal/i386/main.o /Users/davec/fslogger/main.c normal i386 c com.apple.compilers.gcc.4_0
cd /Users/davec/fslogger
/Developer/usr/bin/gcc-4.0 -x c -arch i386 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -Wreturn-type -Wunused-variable -fmessage-length=0 -fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -iquote /Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-generated-files.hmap -I/Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-own-target-headers.hmap -I/Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-all-target-headers.hmap -iquote /Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-project-headers.hmap -F/Users/davec/fslogger/build/Release -I/Users/davec/fslogger/build/Release/include -I/Users/davec/Sources/xnu/bsd/sys -I/Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/DerivedSources -isysroot /Developer/SDKs/MacOSX10.5.sdk -c /Users/davec/fslogger/main.c -o /Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/Objects-normal/i386/main.o
In file included from /Users/davec/fslogger/main.c:9:
/Developer/SDKs/MacOSX10.5.sdk/usr/include/sys/types.h:141: error: syntax error before ‘ino64_t’
/Users/davec/fslogger/main.c:11:26: error: sys/fsevents.h: No such file or directory

It looked like to me that it was trying to use the default system path instead of my path so I copied the command into an test.sh file and started reading up on the gcc options.

test.sh


#!/bin/bash
cd /Users/davec/fslogger

/Developer/usr/bin/gcc-4.0 -x c -arch i386 -pipe -H -Wno-trigraphs -fpascal-strings \
-fasm-blocks -Os -mdynamic-no-pic -Wreturn-type -Wunused-variable -fmessage-length=0 \
-fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 \
-iquote /Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-generated-files.hmap \
-I/Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-own-target-headers.hmap \
-I/Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-all-target-headers.hmap \
-iquote /Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/fslogger-project-headers.hmap \
-F/Users/davec/fslogger/build/Release \
-I/Users/davec/fslogger/build/Release/include \
-I/Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/DerivedSources \
-isysroot /Developer/SDKs/MacOSX10.5.sdk \
-I/Users/davec/Sources/xnu/bsd/sys \
-c /Users/davec/fslogger/main.c \
-o /Users/davec/fslogger/build/fslogger.build/Release/fslogger.build/Objects-normal/i386/main.o

I discovered in the man pages for gcc this little tidbit.


-isystem dir
Search dir for header files, after all directories specified by -I
but before the standard system directories. Mark it as a system
directory, so that it gets the same special treatment as is applied
to the standard system directories.

This sounded to me just what I was looking for so I changed the -I/Users/davec/Sources/xnu/bsd to read -isystem/Users/davec/Sources/xnu/bsd and tried again. Same error! Still can’t find the fsevents.h file! Looking at the source I realized the include files which began with were still going to the wrong place. It must be that if you specify it disregards the -isystem setting. I change the sources to read:


// fslogger.c

#include ‹stdio.h›
#include ‹string.h›
#include ‹fcntl.h›
#include ‹stdlib.h›
#include ‹unistd.h›
#include ‹ioctl.h›
#include ‹types.h›
#include ‹sysctl.h›
#include ‹fsevents.h›
#include ‹pwd.h›
#include ‹grp.h›

int main(int argc, char **argv) {
printf(”Hello world”);
}

Viola! It compiled! So all I have to do now is tell Xcode to use -isystem instead of -I for my xnu headers. Poking around in the docs I found you can specify individual settings for source files if you bring up the info window for the file. Sure enough, there is a Build tab so I put in -isystem/Users/davec/Sources/xnu/bsd and tried building from Xcode.

Bingo! It compiled! Finally!

Hot damn, it even runs!