How can I use a system resource with an absolute path?

Hello everyone,
I am porting a wrapper around libmagic to Swift.

I have a swift package set up to provide a .systemLibrary target to my library and it works fine.

The problem is that I need to include the libmagic database file in my target. For my homebrew install this is located somewhere in /usr/local/share.

My current Package.swift includes:

resources: [
    .copy("/usr/local/share/misc/magic.mgc")
]

But this gives the error:

invalid relative path '/usr/local/share/misc/magic.mgc'; relative path should not begin with '/' or '~'

SPM seems to want only local file references for copied resources. Is there a way to bring this file over without manually copying it over each time I update the underlying library?

Thank you.

Just to be clear: are you sure you want to copy this in to your app's resource bundle? Or do you want to load the system's copy of this file at runtime?

If you are using the system's libmagic and not building your own copy, it would seem more appropriate to load the system's copy of the database file at runtime.

Thank you Karl for replying.

I am building my own library and would like to include my own .mgc file in the app.

As far as I am aware, this library is not included in macOS, and is only distributed as an executable.

I see. But if you're building your own copy of libmagic, does that not come with its own database? It seems strange to build your own copy of the library but not use your own database.

Anyway, to answer your question: maybe :sweat_smile:.

The resources specified in the manifest must be contained within your package folder.

However, package manifests can contain executable code, so you can use Foundation APIs to copy the file in to your package, so that SwiftPM will find it and copy it in to the final product. However (again), manifests are run in a sandboxed environment, and I can't find a good specification detailing exactly what they may/may not do. According to a recent proposal:

Package plugins will be run in a sandbox that prevents network access and restricts writing to the file system to specific intermediate directories. This is the same sandbox that manifest parsing uses, except that it allows writing to a limited set of output directories.

This doesn't say anything about reading system files. Maybe you can, maybe you can't. Maybe it works but isn't guaranteed. :man_shrugging:

Besides executable code in the manifest, your other option would be to use a shell script to copy the file in to the package folder before building. Would that be an option?

It seems strange to build your own copy of the library but not use your own database.

I was going to use the one provided by homebrew, but just realised that is not suitable here. I will instead build my own.

I will however try out your suggestions to see if they work for my own curiosity. Thank you for the help!