On Dec 21, 2005, at 7:15 AM, Gabriele de Simone wrote:
It is (or rather was) my understanding that setting the SDK build setting to anything other than blank or root will cause the -isysroot and -syslibroot flags to be passed to the compiler and linker.
I have since found out that -syslibroot is only passed to libtool (never to ld) and only when creating static libraries.
In Xcode 2.2, Xcode does the following when SDKROOT is set:
1) For each path in HEADER_SEARCH_PATHS, LIBRARY_SEARCH_PATHS and FRAMEWORK_SEARCH_PATHS, the IDE will prepend $(SDKROOT) to the path if and only if that path exists inside the SDK. This means that if that path does *not* exist inside the SDK, the Xcode will not prepend $(SDKROOT) to it. For example, /Developer/SDKs/MacOSX10.4u.sdk does not contain a "/Library" subdirectory, so the IDE will not prepend $(SDKROOT) to /Library (or any subdirectory thereof) which appears in any search path.
(This prepending will show up on the command lines Xcode issues to the compiler and linker, by the way, since Xcode passes explicit -F, -L and -I flags for each path in the search paths.)
2) When invoking the compiler, passes -isysroot $(SDKROOT).
3) When invoking the linker - which it does by invoking the compiler driver - passes -isysroot $(SDKROOT). This causes the compiler driver to pass -syslibroot $(SDKROOT) to the linker.
4) When invoking libtool - which it does directly - passes -syslibroot $(SDKROOT) to the tool.
In other words, Xcode does pass -syslibroot to both the linker and to libtool - it just passes it to the linker implicitly, via passing -isysroot to the compiler driver.
BTW, this only applied to GCC 4.0; GCC 3.3 uses a more complicated mechanism which I won't go into here (because our brains might explode).
The unwanted side effect of doing this is that if the static library links against a dylib in a non-standard location /MyLibs/some.dylib (for example), the linker will always fail to find the library even though the "/MyLibs" path is added to the "Library Search Paths" build setting. It seems that the linker is prepending the SDK path to all of the "Library Search Paths", hence making it impossible to specify an SDK *and* linking against dylibs in non-standard locations.
Is this really what's happening, and is there any way around it?
You may want to check if for some reason the SDK you're building against contains a /MyLibs directory. If so, then you should remove it since it is causing the Xcode IDE to prepend $(SDKROOT) to your search path. Alternately, you could put your libraries in the SDK, but this is not recommended (and shouldn't be necessary unless for some reason your development process makes it desirable).
I'm pretty sure that the compiler and linker do not prepend $(SDKROOT) to directories other than the standard system directories (e.g., /System/Library/Frameworks, /usr/include, etc.). I'm not 100% certain, however, since I haven't worked on those code bases.
A couple of things you can do to examine what's happening yourself:
1) If you pass -v to the compiler (GCC), it will emit a trace of the search paths it is using. If you pass -isysroot as well, then those paths will be prepended with the value passed in with that flag. So you can see just what it's doing.
2) If you pass -t to the linker, it will show you where it is finding all of the files it is linking against. This is not quite the same as -v with the compiler, but is still very useful for debugging. Unfortunately, libtool does not presently support the -t flag (which in your specific case means that this suggestion and 35 cents will buy you a cup of coffee, but it's still a useful debugging tool in many instances).
Hopefully this provides some insight into how the SDK support works, and maybe even enough information to solve your problem. Certainly the *intent* of the SDK support is that you should be able to link against your own libraries in your own directories, rather than having to put all of your own bits into an SDK. The SDK support is intended to redirect where the *system* bits are found.