Xcode 11.4b3: SPM does not see brew deps

In Xcode 11.4b1...b4, when I build my package (swift build) SPM does not see libssh2 installed via brew.

**warning:** you may be able to install libssh2 using your system-packager:

brew install libssh2

...

ld: warning: Could not find or use auto-linked library 'ssh2'
Undefined symbols for architecture x86_64:
  "_libssh2_agent_connect", referenced from:
      _$s5Shout5AgentC7connectyyKF in Agent.swift.o

My package depends on Shout. Is there something changed in SPM? What would be the fix? Should I update the codebase or is this something fixable on Swift toolchain side?

It currently works okay in Xcode 11.3.1. And I do have libssh2 installed:

brew ls --versions libssh2
libssh2 1.9.0_1
3 Likes

When I generate Xcode project and open it, linker also cannot link ssh2.

1 Like

libssh2 is dependent of openssl.
After brew reinstall openssl
You will see:
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
/usr/local/etc/openssl@1.1/certs

and run
/usr/local/opt/openssl@1.1/bin/c_rehash

openssl@1.1 is keg-only, which means it was not symlinked into /usr/local,
because macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH run:
echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc

For compilers to find openssl@1.1 you may need to set:
export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

For pkg-config to find openssl@1.1 you may need to set:
export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"

I have managed to build with:
export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" && \
export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" && \
export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig" && \
swift build

1 Like

I wonder why this has changed. Did SPM put these flags in Xcode 11.3 and stopped doing this in 11.4?

This fixes swift build invocation, but build from Xcode still fails. It seems like SPM does not expose transitive dependencies header search paths or library search paths. Or there is an issue with Shout itself, but I can't identify it yet.

I believe this linker errors appear because of this message:
'CSSH' libssh2.pc: warning: couldn't find pc file

I've checked the sources. SPM executes pkg-config --variable pc_path pkg-config to get search paths. In my shell it returns:

/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig:/usr/lib/pkgconfig:/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.15

libssh2.pc is located at /usr/local/lib/pkgconfig/libssh2.pc, the first search path, so SPM should be able to locate it, but it can't. Investigating further.

In /usr/local/lib/pkgconfig/ there many .pc files. I've tried to replace pkgConfig: "libssh2" with pkgConfig: "liblzma" and warning message about missing .pc file disappeared. I then tried to rename liblzma.pc to 112.pc and I got a warning about missing liblzma.pc. This indicated that something is wrong either with libssh2.pc symlink or with file itself, and that SPM obtains valid search paths.

Both libssh2.pc and liblzma.pc point to the existing .pc files inside brew's CELLAR folder.

image

libssh2.pc has references to libssl.pc and libcrypto.pc. These files only exist inside private brew folders, and there are no symlinks from public locations for these pc files. SPM does not query pkg-config for locations of these files, and unable to locate these files. Apparently the error message about missing libssl2.pc is incorrect, because it misses libssl.pc and libcrypto.pc.

The solution by @gopito allows to build project from command line, since it adds PKG_CONFIG_PATH env which extends search paths. But in Xcode project is still not buildable because this env does not get picked up.

One of the solutions would be to patch brew formulAE to add symbolic links to libssl.pc and libcrypto.pc I guess. Also, these commands fix the link issue:

$ ln -s /usr/local/opt/openssl@1.1/lib/pkgconfig/libcrypto.pc /usr/local/lib/pkgconfig/libcrypto.pc
$ ln -s /usr/local/opt/openssl@1.1/lib/pkgconfig/libssl.pc    /usr/local/lib/pkgconfig/libssl.pc

I guess the correct patch would be to teach SPM to query pkg-config for linker settings like that:

$ pkg-config --libs libssl
-L/usr/local/Cellar/openssl@1.1/1.1.1g/lib -lssl

$ pkg-config --libs libcrypto
-L/usr/local/Cellar/openssl@1.1/1.1.1g/lib -lcrypto

This way there won't be a need to iterate over pkg-config search paths from inside SPM. Also, a setting to extend search paths would be suitable as a fix, but I wasn't able to locate one.

I might be wrong and still mis-understand the concept of pkg-config related stuff though.

I'm still having this issue with recent Xcode 11.6. Did you solve this issue?

I can build fine with both swift build and generated Xcode project from swift package generate-xcodeproj

What's your issue? I wasn't able to build, but you can.

FWIW, here's my script I invoke to link up brew and swift:

Terms of Service

Privacy Policy

Cookie Policy