Search code examples
swiftpackagewhitelistswift-package-managercflags

Swift Package Manager throws nonWhitelistedFlags error


The problem occurs with system modules where it's necessary to use pkgConfig and pkgConfig contains flag definitions.

ImageMagick (homebrewed)

I create two packages: CMagicWand, type system-module

module.modulemap

module CMagickWand [system] {
  header "/usr/local/Cellar/imagemagick/7.0.5-0/include/ImageMagick-7/MagickWand/MagickWand.h"
  link "MagickWand"
  export *
}

Package.swift

import PackageDescription

let package = Package(
    name: "CMagickWand",
    pkgConfig: "MagickWand"
)

Then I try to consume it from the package MagicWand type library

Package.swift

import PackageDescription

let package = Package(
    name: "MagickWand",
    dependencies: [
    .Package(url: "../CMagickWand", majorVersion: 1)
    ]
)

pkgConfig MagickWand.pc

prefix=/usr/local/Cellar/imagemagick/7.0.5-0
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include/ImageMagick-7
includearchdir=/usr/local/Cellar/imagemagick/7.0.5-0/include/ImageMagick-7
libname=MagickWand-7.Q16HDRI

Name: MagickWand
Description: MagickWand - C API for ImageMagick (ABI Q16HDRI)
URL: https://www.imagemagick.org
Version: 7.0.5
Requires: MagickCore
*Cflags: -I${includearchdir} -I${includedir} -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16*
Libs: -L${libdir} -l${libname}
Libs.private: -L${libdir} -l${libname}   -L/usr/local/opt/freetype/lib -lfreetype          -L/usr/local/Cellar/xz/5.2.3/lib -llzma -lbz2 -lz -lltdl  -lm      -lm

With this setup I execute swift build for the second package and the output is following

Cloning /bla-bla-bla/Libraries/CMagickWand
HEAD is now at 30ed4b4 Initial commit
Resolved version: 1.0.0
error: nonWhitelistedFlags("Non whitelisted flags found: [\"-DMAGICKCORE_HDRI_ENABLE=1\", \"-DMAGICKCORE_QUANTUM_DEPTH=16\", \"-DMAGICKCORE_HDRI_ENABLE=1\", \"-DMAGICKCORE_QUANTUM_DEPTH=16\"] in pc file MagickWand")

I tried to remove problematic CFlags from the corresponding .pc file and this doesn't help, even if I figure out how to remove them (I always can create my own .pc file) I don't find it sustainable. These flags are there for a reason.

I have the same problem with mysqlclient on my target system (Ubuntu), the problem is not reproducible on OS X but it doesn't help me:

error: nonWhitelistedFlags("Non whitelisted flags found: [\"-fabi-version=2\", \"-fno-omit-frame-pointer\"] in pc file mysqlclient")

The error comes from the func whitelist (https://github.com/apple/swift-package-manager/blob/master/Sources/PackageLoading/Module%2BPkgConfig.swift) and I don't see any way how to enhance the list during runtime. I don't believe that I'm the only one who struggles with this limitation but I can't find a workaround for a few days already.


Solution

  • I contacted the author of this code and the reply is following:

    The problem here is that we don't allow all flags from a pkg config file because SwiftPM can't reason about them. We have build settings proposal coming up soon which will solve these issues. For now, you can manually pass the flags using swift build -Xcc -Xswiftc -Xld

    So, the only proper way to solve it, for the time being, is to replace flags from .pc files, specify them explicitly while building your project where these packages are imported and pray that those flags will never interfere in case you have several dependencies.

    I created copies for .pc files (yes, files, there are dependencies inside), removed flags and created new links from /usr/local/lib/pkgconfig since I don't want this change to have any side-effects. Works flawlessly with ImageMagick on OS X, will try later on Ubuntu.

    Thank you, Ankit!