Found a way to make this work. By adding an afterEvaluate action to the project, I can iterate over project.sources and then src.cpp.libs for each source.
So my plugin now does something like this:
public class MyCppPlugin implements Plugin<Project> {
void apply(Project project) {
project.apply(plugin: 'cpp')
project.afterEvaluate {
// Setup PROJECT_LIBRARY_DLLSPEC for exported libraries.
project.libraries.each { lib ->
setupDllExportSpec(project, lib.name,
toMacroName(project.name, lib.name, "DLLSPEC"))
}
// Setup PROJECT_LIBRARY_DLLSPEC for imported libraries.
project.sources.each { src ->
src.cpp.libs.each { lib ->
if (lib in Map) {
setupDllImportSpec(project, src.name, lib.get("linkage"),
toMacroName(lib.get("project"), lib.get("library"), "DLLSPEC"))
}
}
}
}
}
// ...
}
Then my setupDllImportSpec() and setupDllExportSpec() methods just iterate over project.binaries and look for matching library/binary names, defining the appropriate cppCompiler preprocessor macro to be __declspec(dllimport), __declspec(dllexport), or the empty string based on linkage.
Note also that I’m using PROJECT_LIBRARY_DLLSPEC macros instead of a single non-namespaced LIB_FUNC macro, since one exported shared library could depend on a different static library.
If there’s a simpler way to do this, I’m definitely open to suggestions. Otherwise, hope this answer helps anyone else trying to accomplish the same thing.