Best way to get modulemap module names programmatically?

occasionally, a SwiftPM package will give a system library a different name than is declared in the Package.swift manifest:

for example, ZipFoundation has a target named CZLib, but the module is actually named CZlib (lowercase l)


module.modulemap

module CZlib {
    header "shim.h"
    link "z"
    export *
}

what is the best way to detect this name programmatically?

If all you care about is the module name, and if the module map is guaranteed to be simple, then your best bet is probably just to do a naïve textual scan of the file.

There are a ton of fun edge (or not-so-edge) cases you might run into though. A modulemap file can contain multiple top-level modules (so a single SwiftPM target could correspond to more than one possible import), submodules are a thing, and you can even have a modulemap that refers to other modulemaps using extern module. So the only truly accurate way to get information out of a modulemap is to build a tool on top of Clang libraries or to reimplement all of that logic, both of which are a bit of a burden.

I wish there was a simple Clang flag you could use to dump the information about a module in a structured parsable format.

1 Like

thanks Tony, it looks like there’s no good way to detect this at the moment. luckily this is not a critical use case as it only affects system library dependencies in SwiftPM projects.

agree it would be great if the toolchain had a way to dump this information to JSON or something.

One way to detect this is that SwiftPM creates a .pcm file for every module in the used module maps in the build directory .build/debug/ModuleCache/, so you could look for what files are in there and dump each pcm file with swiftc -dump-pcm, then check the fields Module map file: and Module name: from that output for all the module names from the module map you want to know about.

I and others have been asking for years for a way to dump the list of C/C++ symbols imported by a module map too, but so far there isn't a way to do that.

1 Like