2

As the title suggests, I am having a bit of trouble creating a static library from C code and having it used in a Swift project.

Here is the make process for the C-Code:

make
# Making the static library
clang -c Sources/nuklear.c -o nuklear.o
clang -c Sources/test.c -o test.o
libtool -static nuklear.o test.o -o libNuklear.a
cp libNuklear.a /usr/local/lib
❯ ls /usr/local/lib | grep Nuk
libNuklear.a

Here is the error:

swift build -Xlinker -L/usr/local/lib
'CNuklear' /Users/pprovins/Projects/CNuklearTest/.build/checkouts/CNuklear: warning: system packages are deprecated; use system library targets instead
ld: warning: Could not find or use auto-linked library 'libNuklear'
Undefined symbols for architecture x86_64:
  "_test_doit", referenced from:
      _main in main.swift.o
ld: symbol(s) not found for architecture x86_64
[0/1] Linking CNuklearTest

The error suggests the library cannot be found or the library is not usable (unable to determine which).

Running nm on libNuklear.a reveals:

libNuklear.a(test.o):
                 U _printf
0000000000000000 T _test_doit

It appears the symbols do exist, so I am leaning toward the possibility of it being an issue finding the library to link against so I shall describe my bridging process next. The C-Code is placed in a system-library module/package separate from the executable being built. It contains a bridging header and package definition. Here is the module.modulemap definition:

module CNuklear [system] {
  header "Includes/CNuklear.h"
  link "libNuklear"
  export *
}

The bridging header (CNuklear.h):

#import "Includes/nuklear.h"
#import "Includes/test.h"

I currently make the static library, then attempt to build the swift executable; however, it is having trouble linking against the static library I have made. Here is how I am attempting to include and execute the code in main.swift:

import CNuklear

test_doit()

print("Hello, world!")

Is there a way to further debug the issue with linking that I am having? Thanks in advance!

1 Answer 1

1

In the module.modulemap file:

If the static library being built is named libNuklear.a, the link specification for the module must be:

module CNuklear [system] {
  header "Includes/CNuklear.h"
  link "Nuklear"
  export *
}

You must also run swift build with -Xlinker -L/usr/local/lib or -Xlinker -L/dir/which/lib/resides

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.