Search code examples
swiftxcodemacosswift-package-managerxcodeproj

How to generate Xcode project using SPM with extra build flags?


I am creating a package that depends on OpenSSL on macOS. To use SPM to build the package, I need to pass it some build/linker flags:

swift build -Xlinker -L/usr/local/opt/openssl/lib -Xcc -I/usr/local/opt/openssl/include

The problem is that when I build my xcode project using SPM, I cannot pass the flags. In theory I would think the following would work,

swift package generate-xcodeproj -Xlinker -L/usr/local/opt/openssl/lib -Xcc -I/usr/local/opt/openssl/include

but it doesn't and once Xcode project is generated, to build in it, I need to go into the Settings and update the appropriate paths.

This is obviously ugly and also it wouldn't work for proper CI workflow, which depend on features that are currently only supported by xcode project and not SPM.

I have already tried passing these values when doing a command line xcodebuild like the following, but that also didn't work.

xcodebuild -project MyProj.xcodeproj -scheme MyProjScheme HEADER_SEARCH_PATHS=/usr/local/opt/openssl/include  LIBRARY_SEARCH_PATHS=/usr/local/opt/openssl/lib  build

Any suggestions?


Solution

  • To create an Xcode project with additional flags, we need to do the following 3 steps:

    Step 1 - Obtain the proper mapping between compiler/linker flags and the equivalent xcode settings. In this case,

    -Xlinker -L/usr/local/opt/openssl/lib -Xcc -I/usr/local/opt/openssl/include
    

    is equivalent to

    HEADER_SEARCH_PATHS=/usr/local/opt/openssl/include
    LIBRARY_SEARCH_PATHS=/usr/local/opt/openssl/lib
    

    Step 2 - Create an .xcconfig file. For example,

    $ less openssl.xcconfig 
    
    HEADER_SEARCH_PATHS = /usr/local/opt/openssl/include 
    LIBRARY_SEARCH_PATHS = /usr/local/opt/openssl/lib
    

    Step 3 - Use the --xcconfig-overrides flag with generate-xcodeproj to make the project use the config file.

     swift package generate-xcodeproj --xcconfig-overrides openssl.xcconfig
    

    Now the Xcode project builds out of the box and xcodebuild can be used without any extra flags.