How to specify include directory for swift build (something like -I and -L in C/C++ world)

Hi, I'm new to swift and I'm learning its internals, package management system, etc. I don't rely on XCode and would like to learn how to do everything from command line (I work on Linux and Mac platforms remotely and no GUI). So, I learn from fast.ai course that we can integrate easily C library into swift. But I have hard time how to properly instruct swift to build against my c library using non-standard location of headers/libs. My question is about how to pass proper flags to swift build that it properly compile code, i.e. something we easily do in C/C++ with -I and -L flags. Here is a problem:

  1. I created new package with swift swift package init --type executable
  2. I created module.modulemap and soxu.h files to point to C library I want to use
    cat Sources/sox/soxu.h
#include <sox.h>

cat Sources/sox/module.modulemap

module sox [system] {
    umbrella header "soxu.h"
    link "sox"
    export *
}
  1. I changed Package.swift to include my sox dependency
    cat Package.swift
import PackageDescription

let package = Package(
name: "SwiftSox",
dependencies: [],
targets: [
    .target(
        name: "SwiftSox",
        dependencies: ["sox"]),
    .testTarget(
        name: "SwiftSoxTests",
        dependencies: ["SwiftSox"]),
    .systemLibrary( name: "sox", pkgConfig: "sox")
]
)
  1. I fired the build
swift build                                                                <<<
/opt/local/include/sox.h:22:10: note: while building module 'Darwin' imported from /opt/local/include/sox.h:22:
#include <limits.h>
         ^
<module-includes>:357:9: note: in file included from <module-includes>:357:
#import "ncurses.h"
        ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include/ncurses.h:141:10: note: in file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include/ncurses.h:141:
#include <unctrl.h>
         ^
/opt/local/include/unctrl.h:61:63: error: unknown type name 'SCREEN'
NCURSES_EXPORT(NCURSES_CONST char *) NCURSES_SP_NAME(unctrl) (SCREEN*, chtype);
                                                              ^
/opt/local/include/sox.h:22:10: note: while building module 'Darwin' imported from /opt/local/include/sox.h:22:
#include <limits.h>
         ^
<module-includes>:357:9: note: in file included from <module-includes>:357:
#import "ncurses.h"
        ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include/ncurses.h:141:10: note: in file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include/ncurses.h:141:
#include <unctrl.h>
         ^
/opt/local/include/unctrl.h:61:53: error: function cannot return function type 'char *(int *, chtype)' (aka 'char *(int *, unsigned int)')
NCURSES_EXPORT(NCURSES_CONST char *) NCURSES_SP_NAME(unctrl) (SCREEN*, chtype);
                                                    ^
/opt/local/include/sox.h:22:10: note: while building module 'Darwin' imported from /opt/local/include/sox.h:22:
#include <limits.h>
         ^
<module-includes>:357:9: note: in file included from <module-includes>:357:
#import "ncurses.h"
        ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include/ncurses.h:141:10: note: in file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include/ncurses.h:141:
#include <unctrl.h>
         ^
/opt/local/include/unctrl.h:61:54: error: a parameter list without types is only allowed in a function definition
NCURSES_EXPORT(NCURSES_CONST char *) NCURSES_SP_NAME(unctrl) (SCREEN*, chtype);
                                                     ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "soxu.h"
        ^
/Users/vk/Work/Languages/Swift/tmp/SwiftSox/Sources/sox/soxu.h:1:10: note: in file included from /Users/vk/Work/Languages/Swift/tmp/SwiftSox/Sources/sox/soxu.h:1:
#include <sox.h>
         ^
/opt/local/include/sox.h:22:10: error: could not build module 'Darwin'
#include <limits.h>
         ^
/Users/vk/Work/Languages/Swift/tmp/SwiftSox/Sources/SwiftSox/main.swift:1:8: error: could not build Objective-C module 'sox'
import sox
       ^

As you can see, the problem is that my C sources are located in /opt/local/include, e.g. sox.h which resolves limits.h and ncurses.h, but swift build takes the ncurses.h from Xcode location instead of /opt/local/include and it cause an error due to incompatibility between headers in /opt/local/include and Xcode location. My understanding that I should tell properly swift build command to pick-up all sources from /opt/local/include first (before anything in XCode) and then properly link C libraries.

How I can resolve this situation?
Thanks,
Valentin.

The question would be a better fit for the "Using Swift" category. :slightly_smiling_face: The Development/Compiler category is for asking questions related to work on the Swift compiler.

I don't know if there is a safe way to do this, maybe you can use unsafeFlags? Say something like -Xswiftc -I -Xswiftc /opt/local/include?

Check this link https://www.hackingwithswift.com/articles/87/how-to-wrap-a-c-library-in-swift I have followed the exact steps and works fine for me.

This is not correct try the option swift package init --type system-module

Terms of Service

Privacy Policy

Cookie Policy