Static Library linking Error - xcode

Getting an Apple Mach-O Librarian Error when trying to archive my project.
I have an Xcode project that links to an FDLibrary. Its a static library contained in the same workspace. FDLibrary links to an SDLibrary. Another static library also contained in the workspace.
I know its unconventional to have multiple static libraries however the SDLibrary contains a lot of common code to several apps while the FDLibrary contains a lot of common code built on the SDLibrary only needed by a few apps. Most basically the FDLibrary contains a lot of specific interface templates while the SDLibrary is almost all data structures and object types.
Building and Running to device works completely fine. But I started to archive today and ran into this error.
All hints welcome! Thanks in advance!
Libtool "/Users/rpools1951/Library/Developer/Xcode/DerivedData/FunDecks-fqrkiylcrromdnbuuyxoyjotckal/Build/Intermediates/ArchiveIntermediates/Irregular Verbs/IntermediateBuildFilesPath/FDLibrary.build/Release-iphoneos/FDLibrary.build/Objects-normal/armv7s/libFDLibrary.a" normal armv7s
cd /Users/rpools1951/Projects/Workspaces/FDLibrary
setenv IPHONEOS_DEPLOYMENT_TARGET 6.0
setenv PATH "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static -arch_only armv7s -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk "-L/Users/rpools1951/Library/Developer/Xcode/DerivedData/FunDecks-fqrkiylcrromdnbuuyxoyjotckal/Build/Intermediates/ArchiveIntermediates/Irregular Verbs/BuildProductsPath/Release-iphoneos" -LSDLibrary -filelist "/Users/rpools1951/Library/Developer/Xcode/DerivedData/FunDecks-fqrkiylcrromdnbuuyxoyjotckal/Build/Intermediates/ArchiveIntermediates/Irregular Verbs/IntermediateBuildFilesPath/FDLibrary.build/Release-iphoneos/FDLibrary.build/Objects-normal/armv7s/FDLibrary.LinkFileList" -ObjC -framework UIKit -lSDLibrary -framework Foundation -o "/Users/rpools1951/Library/Developer/Xcode/DerivedData/FunDecks-fqrkiylcrromdnbuuyxoyjotckal/Build/Intermediates/ArchiveIntermediates/Irregular Verbs/IntermediateBuildFilesPath/FDLibrary.build/Release-iphoneos/FDLibrary.build/Objects-normal/armv7s/libFDLibrary.a"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: -dynamic not specified the following flags are invalid: -ObjC
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -lSDLibrary
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -lSDLibrary is not an object file (not allowed in a library)
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool failed with exit code 1

Related

Xcode "ld: library not found [...] for architecture x86_64"

I want to include libgpg-error and libgcrypt in my swift-project and created the following module.modulemaps:
libgpgerror:
module libgpgerror {
header "/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/gpg-error.h"
link "'/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/libgpgerror-1.21.dylib'"
export *
}
libgcrypt:
module libgcrypt {
header "/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgcrypt/gcrypt.h"
link "'/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgcrypt/libgcrypt-1.6.5.dylib'"
export *
}
I also added the "Swift Compiler - Search Path/Import Paths": /Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/** to both project and target.
The modules are found, the paths are correct.
However if I want to compile the project I get the following error:
ld: library not found for -l'/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/libgpgerror-1.21.dylib' for architecture x86_64
But if I do
file /Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/libgpgerror-1.21.dylib
I get the output
/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/libgpgerror-1.21.dylib: Mach-O 64-bit dynamically linked shared library x86_64
So it seems the library is in the correct place and also has the correct architecture.
Edit
I found a workaround: I removed the link-directive from the modulemaps and linked the libraries manually; this seems to work. But why?
module libgpgerror {
header "/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/gpg-error.h"
export *
}
The link directive specifies only the name of the linked library. That is it should specify the suffix of the linker flag for the library. It appears that the directive take "-l" and concatenates the name to produce the linker flag.
This means that the correct way to specify your module map is as follows.
module CGcrypt {
header "/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgcrypt/gcrypt.h"
link "gcrypt"
export *
}
This will generate the linker flag -lgcrypt which is the correct linker flag.
However, there is another problem which is that the linker needs to be able to find the dylib file for gcrypt and by default it only looks on certain paths. Those paths can be found by running clang -Xlinker -v. The output for me looks like this:
tylercloutier$ clang -Xlinker -v
#(#)PROGRAM:ld PROJECT:ld64-264.3.101
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS)
Library search paths:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/lib
... more stuff ...
Now I'm not sure, but I suspect that the normal search paths are probably
/usr/lib
/usr/local/lib
but I think that Xcode has altered my search paths to point the the MacOSX10.11.sdk/usr/lib, which, incidentally, has basically the same set of files as /usr/lib (they are not symlinked). Indeed, in El Capitan, because of System Integrity Protection even sudo will not allow you to edit /usr/lib.
Thus the problem that I am having is that even though I've installed my libraries to /usr/local/lib, clang is not able to link them. In order to fix that I can specify the search path explicitly.
swift build -Xlinker -L/usr/local/lib/
And we're off to the races. I can even generate an xcodeproj which will have the appropriate linker flag already set in Other Linker Flags.
swift build -Xlinker -L/usr/local/lib/ --generate-xcodeproj
If you leave out the link directive in the module map file, you can specify it as a flag:
module CGcrypt {
header "/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgcrypt/gcrypt.h"
export *
}
Like so
swift build -Xlinker -L/usr/local/lib/ -lgcrypt
How to change the default library search paths, I don't know. But it would be great if someone else could shed light on this matter!

Xcode 6.2 OSX Undefined symbols for functions in other files

I'm sure this is a total nube question but if someone could explain to me what's going wrong I'd be very grateful.
I create a new Cocoa App in XCode. Call it LinkerTest. This basic app will build and run, putting a simple blank window up.
Add a new .cpp file using the C++ File template. Call it Test.cpp. This creates Test.h too.
In Test.cpp add a simple function:
int TestMe(void)
{
return 1;
}
Declare my function in Test.h
int TestMe(void);
In my AppDelegate.m (which was created automatically when I create the app) add
#include "Test.h"
In the applicationDidFinishLaunching method add:
printf("Test = %d\n", TestMe());
Now try to build. Everything compiles ok, but it fails to link. This is the linker command:
Ld Build/Products/Debug/LinkerTest.app/Contents/MacOS/LinkerTest normal x86_64
cd /Users/chip/LinkerTest
export MACOSX_DEPLOYMENT_TARGET=10.10
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -L/Users/chip/LinkerTest/Build/Products/Debug -F/Users/chip/LinkerTest/Build/Products/Debug -filelist /Users/chip/LinkerTest/Build/Intermediates/LinkerTest.build/Debug/LinkerTest.build/Objects-normal/x86_64/LinkerTest.LinkFileList -Xlinker -rpath -Xlinker #executable_path/../Frameworks -mmacosx-version-min=10.10 -stdlib=libc++ -fobjc-arc -fobjc-link-runtime -Xlinker -dependency_info -Xlinker /Users/chip/LinkerTest/Build/Intermediates/LinkerTest.build/Debug/LinkerTest.build/Objects-normal/x86_64/LinkerTest_dependency_info.dat -o /Users/chip/LinkerTest/Build/Products/Debug/LinkerTest.app/Contents/MacOS/LinkerTest
And this is the error I get:
Undefined symbols for architecture x86_64:
"_TestMe", referenced from:
-[AppDelegate applicationDidFinishLaunching:] in AppDelegate.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
So any idea what I've done wrong? Seems to me that adding the file it should link too, but it doesn't. I know the file Test.cpp gets compiled, if I add garbage to the file, then the compiler immediately yacks on that garbage.
EDIT: A couple more things.
1) Looking at this stackoverflow(Getting XCode to include, compile and link existing (C++) codebase in XCode 4.3(.1)) question it seems similar but not my issue. I can confirm that my test.cpp is listed in my Compile Sources under Build Phases.
2) Looking in the LinkerTest/Build/Intermediates/LinkerTest.build/Debug/LinkerTest.build/Objects-normal/x86_64 folder I find Test.o, Test.d, and Test.dia which suggests to me that Test.cpp is in fact compiling. In that folder I also find LinkerTest.LinkFileList which when opened with a text editor shows that Test.o should be linked.
The answer is that when you create a default Cocoa app the AppDelegate file is a .m file. Changing that file to be AppDelegate.mm fixes the problem. My uninformed guess is that a .m file will only handle .c files and to correctly handle .cpp files you must use .mm files. Why xcode's default files for a default Cocoa App wouldn't be .mm files is beyond my pay grade, but there it is.

How does Xcode generate the list of framework directories used in the final linking step?

question:
How does Xcode generate the list of framework directories (-F flags in the call to ld) when building a Cocoa app? I keep getting a warning for an old directory which (I think) I have removed from the project settings.
details:
I moved a working Xcode project from one directory to another. I had to fix some broken references to frameworks that now have a different relative path. Everything appears to be working, except for a single warning on the final linker step:
ld: warning: directory '../Some/Path/To/Framework' following -F not found
../Some/Path/To/Framework is definitely part of the old setup. The external frameworks were stored in a directory that was one level up from the project file.
The full text of the call to ld looks something like this (lightly sanitized):
Ld /Volumes/Projects/Builds/Debug/MyApp.app/Contents/MacOS/MyApp normal i386
cd /Volumes/Projects/MyApp
setenv MACOSX_DEPLOYMENT_TARGET 10.6
/Developer/usr/bin/gcc-4.2 -arch i386 -isysroot /Developer/SDKs/MacOSX10.6.sdk
-L/Volumes/Projects/Builds/Debug -F/Volumes/Projects/Builds/Debug
-F../Some/Path/To/Framework
-F/Correct/Path/To/Framework
-filelist /Volumes/Projects/Builds/MyApp.build/Debug/MyApp.build/
Objects-normal/i386/MyApp.LinkFileList
-mmacosx-version-min=10.6
-framework Cocoa
-framework FRAMEWORK
-framework Carbon
-framework Quartz
-o /Volumes/Projects/Builds/Debug/MyApp.app/Contents/MacOS/MyApp
The warning is triggered by that old value for -F. I have searched through all of the build settings, and everything points to /Correct/Path/To/Framework, not ../Some/Path/To/Framework. I have also cleaned the entire build, but to no avail.
Check your build settings. The framework search paths are under Framework Search Paths, or build variable FRAMEWORK_SEARCH_PATHS.

Duplicate symbol from single library in iOS4.1 SDK

I am developing an iPhone application. I am unfamiliar with Xcode, so please bear with me. I have the iOS 4.1 Device SDK. When I select "Simulator" in the "Active ..." drop-down box, my application compiles without errors and runs in the iPhone simulator.
When I select "Device" in the drop-down box, however, I get the following linker error regarding a duplicate symbol:
Ld build/PineCone.build/Debug-iphoneos/PineCone.build/Objects-normal/armv6/PineCone normal armv6
cd /Users/isaacsutherland/fydp/PineCone/PineCone
setenv IPHONEOS_DEPLOYMENT_TARGET 4.1
setenv PATH "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.1.sdk -L/Users/isaacsutherland/fydp/PineCone/PineCone/build/Debug-iphoneos -L/Users/isaacsutherland/fydp/PineCone/PineCone/../3rd/libGHUnitIPhone -F/Users/isaacsutherland/fydp/PineCone/PineCone/build/Debug-iphoneos -filelist /Users/isaacsutherland/fydp/PineCone/PineCone/build/PineCone.build/Debug-iphoneos/PineCone.build/Objects-normal/armv6/PineCone.LinkFileList -dead_strip -all_load -ObjC -miphoneos-version-min=4.1 -framework Foundation -framework UIKit -framework CoreGraphics /Users/isaacsutherland/fydp/PineCone/3rd/three20/Build/Products/Debug-iphoneos/libThree20.a /Users/isaacsutherland/fydp/PineCone/3rd/three20/Build/Products/Debug-iphoneos/libThree20Core.a /Users/isaacsutherland/fydp/PineCone/3rd/three20/Build/Products/Debug-iphoneos/libThree20Network.a /Users/isaacsutherland/fydp/PineCone/3rd/three20/Build/Products/Debug-iphoneos/libThree20Style.a /Users/isaacsutherland/fydp/PineCone/3rd/three20/Build/Products/Debug-iphoneos/libThree20UI.a /Users/isaacsutherland/fydp/PineCone/3rd/three20/Build/Products/Debug-iphoneos/libThree20UICommon.a /Users/isaacsutherland/fydp/PineCone/3rd/three20/Build/Products/Debug-iphoneos/libThree20UINavigator.a -framework QuartzCore -framework CFNetwork -framework MobileCoreServices -framework SystemConfiguration -lz.1.2.3 /Users/isaacsutherland/fydp/PineCone/ClientDal/build/Debug-iphoneos/libClientDal.a -lGHUnitIPhone4_0 -o /Users/isaacsutherland/fydp/PineCone/PineCone/build/PineCone.build/Debug-iphoneos/PineCone.build/Objects-normal/armv6/PineCone
ld: duplicate symbol _RedirectionLimit in /Users/isaacsutherland/fydp/PineCone/ClientDal/build/Debug-iphoneos/libClientDal.a(libASIHTTPRequest.a-armv6-master.o) and /Users/isaacsutherland/fydp/PineCone/ClientDal/build/Debug-iphoneos/libClientDal.a(libASIHTTPRequest.a-armv6-master.o)
collect2: ld returned 1 exit status
Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 failed with exit code 1
The error is strange because it complains that _RedirectionLimit is found twice -- in the same file! libClientDal.a(libASIHTTPRequest.a-armv6-master.o) is the offending library. Can someone help me understand what is going on? How could this library have compiled properly in the first place? Or perhaps the linker is trying to include the same library twice?
The workaround provided in this similar question does not work for me.
If you need more information, I will gladly provide it -- as I said, I'm new to Xcode development.
When you have a web of projects that compile to static libraries and refer to one another, there are 2 distinct concerns you must consider:
A project's Direct Dependencies inform Xcode which projects depend on each other so it knows to recompile a project when its dependencies change.
A project's Linked Libaries actually get included in its object code.
In a nutshell, your web of direct dependencies can be as tangled as you want, but you must be careful to link each project's code into the application executable only once.
Basically, my problem was that I had 3 projects A, B, and C, and the dependencies looked like A=>B, A=>C, B=>C. I was linking libC.a into both A and B, so the linker complained about duplicate code.
The configuration stuff you need to change is on the Target Info page for each of your projects' targets.
This happened to me when I used the -all_load linker flag, which forces the linker to load all symbols from all libraries. The Three20 project says you should use it, because otherwise the Categories won't be loaded and you get a runtime exception. I removed that flag, and added the -force_load flag just for each library that needed it (the Three20 libraries). See also: What does the -all_load linker flag do?
I've several apps that need to embed a small custom library that makes use of ASI and TBXML. Some of this apps have their own version of that libraries. In order to avoid duplicate symbol issue, I duplicated the each library's target removing the .m files that causes the issue.
Hope it helps.

How can my XCode project files be exactly the same as a working project and still have build errors?

I'm following a tutorial from chapter 12 of the book "Beginning iPhone 3 Development." When I try to build the project I get an error. The book came with the project files, so I went through every file in my Classes directory and copied and pasted the code from the example project so that they are identical. This has solved my build errors in the past. I checked that the same frameworks were installed and the files in the Other Sources and Resources folder are identical. Still, when I try to build, I get the following build error:
Ld
build/Debug-iphonesimulator/GLFun.app/GLFun
normal i386 cd
/Users/gin/Documents/development/GLFun
setenv MACOSX_DEPLOYMENT_TARGET 10.5
setenv PATH
"/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2
-arch i386 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.3.sdk
-L/Users/gin/Documents/development/GLFun/build/Debug-iphonesimulator
-F/Users/gin/Documents/development/GLFun/build/Debug-iphonesimulator
-filelist /Users/gin/Documents/development/GLFun/build/GLFun.build/Debug-iphonesimulator/GLFun.build/Objects-normal/i386/GLFun.LinkFileList
-mmacosx-version-min=10.5 -framework Foundation -framework UIKit -framework
CoreGraphics -framework OpenGLES
-framework QuartzCore -o /Users/gin/Documents/development/GLFun/build/Debug-iphonesimulator/GLFun.app/GLFun
ld: duplicate symbol
.objc_class_name_GLFunView in
/Users/gin/Documents/development/GLFun/build/GLFun.build/Debug-iphonesimulator/GLFun.build/Objects-normal/i386/GLFunView-7A51E8797CBB3D72.o
and
/Users/gin/Documents/development/GLFun/build/GLFun.build/Debug-iphonesimulator/GLFun.build/Objects-normal/i386/GLFunView-7A51E8797CBB3D72.o
From what I can see my project is identical to the one supplied with the book, which I can build and run successfully. What could possibly still be different that is causing this error?
Use diff(1) between the two projects' project.pbxproj files and find out.
Clean the project then try again, sometimes strange things happen. Check the build configurations between the two projects to see if they have any differences (building for the same architecture, sdk, etc.). Since you have duplicate symbols my first guess would be that Clean will solve your issue.

Resources