Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 *
}
like image 968
K. Biermann Avatar asked Feb 10 '16 16:02

K. Biermann


1 Answers

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!

like image 184
Tyler Cloutier Avatar answered Nov 18 '22 19:11

Tyler Cloutier