xanderdunn
(Xander Dunn)
1
I am attempting to make a cross-platform macOS and Linux library that imports the HDF5 C library. HDF5 can be installed on macOS with brew hdf5 or on Ubuntu 18.04 with sudo apt install libhdf5-serial-dev. This installs files in these locations:
On macOS:
- Library: /usr/local/lib/libhdf5.*
- Header: /usr/local/include/hdf5.h
- To build:
swift build -Xlinker -L/usr/local/lib/
On Ubuntu:
- Library: /usr/lib/x86_64-linux-gnu/hdf5/serial/libhdf5.*
- Headher: /usr/include/hdf5/serial/hdf5.h
- To build:
swift build -Xlinker -L/usr/lib/x86_64-linux-gnu/hdf5/serial
HDF5 does not appear to support pkg-config and hence does not contain a .pc file.
Currently, this is my full module.modulemap:
module CHDF5 [system] {
// Linux:
// Lib is at /usr/lib/hdf5/serial/libhdf5.*
// umbrella header "/usr/include/hdf5/serial/hdf5.h"
// macOS:
// Lib is at /usr/local/lib/libhdf5.*
umbrella header "/usr/local/include/hdf5.h"
link "hdf5"
export *
}
To compile on one platform vs the other I have to uncomment the appropriate line.
I attempted to do the following in the module.modulemap:
#if os(Linux)
#else
#endif
But these lines were not recognized as valid tokens.
Is there no way to do a system module import on a library that doesn't have built-in pkg-config support that is cross-platform compatible?
Clone the full code to reproduce here.
All of the above is on Xcode 12's Swift 5.3 release.
lukasa
(Cory Benfield)
2
The easiest way is to make your umbrella header local to your package and then #include <hdf5.h> in that header. That will achieve your desired outcome, as the C compiler will search the include paths on the system and find that header.
However, you’ll probably then run into SR-12909. I don’t know a good way to work around that at present.
1 Like
xanderdunn
(Xander Dunn)
3
Excellent, that's what I was looking for, thanks @lukasa! You're right, the final hurdle to true cross-platform compatibility with a simple swift build is that the linker doesn't find the libraries. I still have to build with either swift build -Xlinker -L/usr/local/lib/ on macOS or swift build -Xlinker -L/usr/lib/x86_64-linux-gnu/hdf5/serial on Linux. Thanks for the link to the bug report.
xanderdunn
(Xander Dunn)
4
One solution to this I hadn't thought of is in this article. In the .modulemap, specify two different modules: One for Mac and one for Linux. They have different header paths and the right one is important with an #if canImport.