Trouble including C library

So I've wasted a week trying to get this to work and figure it's time to ask for help. I'm a C neophyte so this is my first time using things like make and Makefile, which at the moment is mostly voodoo to me.
I'm trying to build and include a C library, but no matter what I try I get this error:

arm-none-eabi-gcc: error: libchipmunk: No such file or directory

Here are my steps:

# List the user directory to look for the libraries here
ULIBDIR = chipmunk/src

# List all user libraries here
ULIBS = libchipmunk
  • In src/main.c I add: #include "chipmunk.h" to test that everything is linked correctly after the build
  • I then run make from the project root, and I get the error at the top of the thread.
  • I have also tried other variations like ULIBS = chipmunk/src/libchipmunk since I noticed the SRC variable needs the full relative path, but that didn't fix it.

It feels like ULIBDIR and ULIBS are the two variables I should be updating to get make to link the library, but I have not seen any example playdate project Makefiles where someone is including a library so I'm not sure.

Try

ULIBS = -lchipmunk

or

ULIBS = chipmunk/src/libchipmunk.a

(untested, just from a quick look into PlaydateSDK/C_API/buildsupport/common.mk where these variables are used.)

If you need libchipmunk.a, feel free to use mine: wheelsprung/lib/macos at main · ninovanhooff/wheelsprung · GitHub

Since I use Nim, I'm unsure how much of the remainder of my project is relevant to you

Note: there is an issue with the windows version*, but the Mac one I linked to above should work

  • the windows version does not include all dependencies and apparently requires a MingW toolchain to be installed for the simulator to find the required dll.

I never thought I would miss python so much.

@CWalther the following change allowed me take one step forwards, thanks for the suggestion:

ULIBS = -lchipmunk

Why it is "chipmunk" and not "libchipmunk" (since the latter is the actual name of the file that gets created) is beyond me, maybe I need to look into the common.mk as you suggested to see what wizardry its performing.

...

However, after making that fix I immediately hit another error:

src/main.c:13:10: fatal error: 'chipmunk.h' file not found

Which is baffling to me because I thought a library packaged the source and header files together...but I guess that's not the case? Thankfully it was easy enough to fix by adding the following:

# List all user include directories here
UINCDIR = chipmunk/include chipmunk/include/chipmunk

WHICH LEADS ME to build error #3 (I guess most people spend more time getting their code to compile than actually work on logic, eh?). After getting gcc to recognize the library and the header files, now I'm getting the following when I try to actually utilize any of the functions or structs from the lib:

/usr/local/playdate/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: /usr/local/playdate/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libg.a(lib_a-readr.o): in function `_read_r':
readr.c:(.text._read_r+0x14): undefined reference to `_read'
collect2: error: ld returned 1 exit status
make: *** [build/pdex.elf] Error 1

...so I looked that error up online and tried adding the following at the bottom of the Makefile:

LDFLAGS += --specs=nosys.specs

Which brings me to another new unique error:

clang -g -dynamiclib -rdynamic -lm -DTARGET_SIMULATOR=1 -DTARGET_EXTENSION=1 -I . -I /Users/chendryx/Developer/PlaydateSDK/C_API -I chipmunk/include -I chipmunk/include/chipmunk -o build/pdex.dylib src/main.c /Users/chendryx/Developer/PlaydateSDK/C_API/buildsupport/setup.c
ld: Undefined symbols:
  _cpSpaceFree, referenced from:
      _update in main-056dea.o
  _cpSpaceNew, referenced from:
      _update in main-056dea.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [build/pdex.dylib] Error 1

...and now I'm stuck again.

:person_shrugging: It’s some kind of time-honored UNIX tradition that a library named abc is stored in a file named libabc.a (or libabc.dylib or libabc.so) and to link to it you give command line option -labc to the linker.

No, what you’re thinking of is a framework, which bundles a library (containing executable code) and its headers together (a macOS-/NeXTStep-specific concept). Neither includes source files.

Hmm, looks like the compiler command line for the simulator in common.mk is not set up for linking to additional libraries. I’m not sure how that’s supposed to work, maybe you’re the first one to try that? I don’t immediately see any way around that without editing common.mk to add another variable to the end of the line that starts with $(SIMCOMPILER), e.g. $(SIMLIBS) and then setting either SIMLIBS = -Lchipmunk/src -lchipmunk or SIMLIBS = chipmunk/src/libchipmunk.dylib in your makefile.

Or, if you’re satisfied with building only for the device, not for the simulator, just run make device instead of make.

make device works without me having to change anything, and it opens in the simulator just fine but I'm not getting any output in the console (ie from logToConsole), which I guess is a consequence of building for the device?

sigh probably best just to admit defeat for now, instead of trying to build a library I'll just include all of the chipmunk files as src as seen in jalaxchapman's lua/C example.

Thanks for the advice chaps, I feel approximately 3% more knowledgeable about make, wish I had reached out sooner instead of pulling my hair out and trying to piece together random bits of information from stack overflow.

Here's the stuff I added/updated from the HelloWorld Makefile, which seems to be working (and I imagine compiles just the same as the library would):

CHIPSRC = $(shell ls chipmunk/src/*.c)
VPATH += chipmunk/src
SRC += $(CHIPSRC)
UINCDIR = chipmunk/include chipmunk/include/chipmunk
// this last line I just copied from jalaxchapman's without knowing what it does
// but it seems to be necessary
LDFLAGS += --specs=nosys.specs