Skip to content

[libclang][Dependency Scanning] Implementing C-APIs to Report a Module's Link Libraries #10994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions clang/include/clang-c/Dependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,56 @@ CINDEX_LINKAGE enum CXErrorCode
clang_experimental_DependencyScanner_generateReproducer(
CXDependencyScannerReproducerOptions CXOptions, CXString *MessageOut);

/**
* An opaque object that contains a \c CXDepGraphModule 's list of link
* libraries.
*/
typedef struct CXOpaqueDepGraphModuleLinkLibrarySet
*CXDepGraphModuleLinkLibrarySet;

/**
* An opaque object that contains information about a link library.
*/
typedef struct CXOpaqueDepGraphModuleLinkLibrary *CXDepGraphModuleLinkLibrary;

/**
* Get the set of link libraries given a \c CXDepGraphModule instance.
* The returned set is a pointer into memory that the \c CXDepGraphModule
* instance owns. Therefore the set does not need to be disposed.
*/
CINDEX_LINKAGE CXDepGraphModuleLinkLibrarySet
clang_experimental_DepGraphModule_getLinkLibrarySet(CXDepGraphModule);

/**
* Get the size of \c CXDepGraphModuleLinkLibrarySet .
*/
CINDEX_LINKAGE size_t clang_experimental_DepGraphModuleLinkLibrarySet_getSize(
CXDepGraphModuleLinkLibrarySet);

/**
* Retrieve the \c CXDepGraphModuleLinkLibrary instance at index \p Idx from the
* \c CXDepGraphModuleLinkLibrarySet instance.
*/
CINDEX_LINKAGE CXDepGraphModuleLinkLibrary
clang_experimental_DepGraphModuleLinkLibrarySet_getLinkLibrary(
CXDepGraphModuleLinkLibrarySet, size_t Idx);

/**
* Get the `Library` string from the \c CXDepGraphModuleLinkLibrary instance.
* `Library` could be a library name, or an absolute path to a library or a
* framework, as specified in the corresponding \c CXDepGraphModule instance's
* modulemap.
*/
CINDEX_LINKAGE CXString clang_experimental_DepGraphModuleLinkLibrary_getLibrary(
CXDepGraphModuleLinkLibrary);

/**
* Returns true if the \c CXDepGraphModuleLinkLibrary is a framework, false
* otherwise.
*/
CINDEX_LINKAGE bool clang_experimental_DepGraphModuleLinkLibrary_isFramework(
CXDepGraphModuleLinkLibrary);

/**
* @}
*/
Expand Down
4 changes: 4 additions & 0 deletions clang/test/Index/Core/Inputs/module/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ module ModA {
header "SubSubModA.h"
}
}

link framework "libModA"
link "libModB"
link "/absolute/path/to/a/lib/file"
}
4 changes: 4 additions & 0 deletions clang/test/Index/Core/scan-deps-by-mod-name.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
// CHECK-NEXT: [[PREFIX]]/Inputs/module/ModA.h
// CHECK-NEXT: [[PREFIX]]/Inputs/module/SubModA.h
// CHECK-NEXT: [[PREFIX]]/Inputs/module/SubSubModA.h
// CHECK-NEXT: link libraries:
// CHECK-NEXT: libModA(framework)
// CHECK-NEXT: libModB
// CHECK-NEXT: /absolute/path/to/a/lib/file
// CHECK-NEXT: build-args: {{.*}} -emit-module {{.*}} -fmodule-name=ModA {{.*}} -fno-implicit-modules {{.*}}
// CHECK-NEXT: dependencies:
// CHECK-NEXT: command 0:
Expand Down
8 changes: 8 additions & 0 deletions clang/test/Index/Core/scan-deps-cas.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
// CHECK-NEXT: [[PREFIX]]/Inputs/module/ModA.h
// CHECK-NEXT: [[PREFIX]]/Inputs/module/SubModA.h
// CHECK-NEXT: [[PREFIX]]/Inputs/module/SubSubModA.h
// CHECK-NEXT: link libraries:
// CHECK-NEXT: libModA(framework)
// CHECK-NEXT: libModB
// CHECK-NEXT: /absolute/path/to/a/lib/file
// CHECK-NEXT: build-args:
// CHECK-SAME: -cc1
// CHECK-SAME: -fcas-path
Expand Down Expand Up @@ -85,6 +89,10 @@
// INCLUDE_TREE-NEXT: [[PREFIX]]/Inputs/module/ModA.h
// INCLUDE_TREE-NEXT: [[PREFIX]]/Inputs/module/SubModA.h
// INCLUDE_TREE-NEXT: [[PREFIX]]/Inputs/module/SubSubModA.h
// INCLUDE_TREE-NEXT: link libraries:
// INCLUDE_TREE-NEXT: libModA(framework)
// INCLUDE_TREE-NEXT: libModB
// INCLUDE_TREE-NEXT: /absolute/path/to/a/lib/file
// INCLUDE_TREE-NEXT: build-args:
// INCLUDE_TREE-SAME: -cc1
// INCLUDE_TREE-SAME: -fcas-path
Expand Down
4 changes: 4 additions & 0 deletions clang/test/Index/Core/scan-deps.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
// CHECK-NEXT: [[PREFIX]]/Inputs/module/ModA.h
// CHECK-NEXT: [[PREFIX]]/Inputs/module/SubModA.h
// CHECK-NEXT: [[PREFIX]]/Inputs/module/SubSubModA.h
// CHECK-NEXT: link libraries:
// CHECK-NEXT: libModA(framework)
// CHECK-NEXT: libModB
// CHECK-NEXT: /absolute/path/to/a/lib/file
// CHECK-NEXT: build-args: {{.*}} -emit-module {{.*}} -fmodule-name=ModA {{.*}} -fno-implicit-modules {{.*}}

// CHECK-NEXT: dependencies:
Expand Down
19 changes: 19 additions & 0 deletions clang/tools/c-index-test/core_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,25 @@ static int scanDeps(ArrayRef<const char *> Args, std::string WorkingDirectory,
// (mostly) platform-agnostic.
if (!StringRef(FileName).ends_with("SDKSettings.json"))
llvm::outs() << " " << FileName << "\n";
CXDepGraphModuleLinkLibrarySet LinkLibs =
clang_experimental_DepGraphModule_getLinkLibrarySet(Mod);
size_t NumLinkLibs =
clang_experimental_DepGraphModuleLinkLibrarySet_getSize(LinkLibs);
if (NumLinkLibs) {
llvm::outs() << " link libraries:\n";
for (size_t Idx = 0; Idx < NumLinkLibs; Idx++) {
CXDepGraphModuleLinkLibrary Lib =
clang_experimental_DepGraphModuleLinkLibrarySet_getLinkLibrary(
LinkLibs, Idx);
CXString Library =
clang_experimental_DepGraphModuleLinkLibrary_getLibrary(Lib);
bool IsFramework =
clang_experimental_DepGraphModuleLinkLibrary_isFramework(Lib);
const char *IsFrameworkStr = IsFramework ? "(framework)" : "";
llvm::outs() << " " << clang_getCString(Library)
<< IsFrameworkStr << "\n";
}
}
llvm::outs() << " build-args:";
for (const auto &Arg :
ArrayRef(BuildArguments.Strings, BuildArguments.Count))
Expand Down
42 changes: 42 additions & 0 deletions clang/tools/libclang/CDependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -882,3 +882,45 @@ enum CXErrorCode clang_experimental_DependencyScanner_generateReproducer(
"located at:\n "
<< FileCachePath << "\n " << ReproScriptPath;
}

namespace {
typedef llvm::SmallVectorImpl<clang::Module::LinkLibrary>
DepGraphModuleLinkLibrarySet;
typedef clang::Module::LinkLibrary DepGraphModuleLinkLibrary;
} // namespace

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DepGraphModuleLinkLibrarySet,
CXDepGraphModuleLinkLibrarySet)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DepGraphModuleLinkLibrary,
CXDepGraphModuleLinkLibrary)

CXDepGraphModuleLinkLibrarySet
clang_experimental_DepGraphModule_getLinkLibrarySet(CXDepGraphModule CXDepMod) {
const ModuleDeps &ModDeps = *unwrap(CXDepMod)->ModDeps;
return wrap(&ModDeps.LinkLibraries);
}

size_t clang_experimental_DepGraphModuleLinkLibrarySet_getSize(
CXDepGraphModuleLinkLibrarySet S) {
const DepGraphModuleLinkLibrarySet *LinkLibraries = unwrap(S);
return LinkLibraries->size();
}

CXDepGraphModuleLinkLibrary
clang_experimental_DepGraphModuleLinkLibrarySet_getLinkLibrary(
CXDepGraphModuleLinkLibrarySet S, size_t Idx) {
const DepGraphModuleLinkLibrarySet *LinkLibraries = unwrap(S);
return wrap(&(*LinkLibraries)[Idx]);
}

CXString clang_experimental_DepGraphModuleLinkLibrary_getLibrary(
CXDepGraphModuleLinkLibrary L) {
const DepGraphModuleLinkLibrary *Lib = unwrap(L);
return cxstring::createRef(Lib->Library.c_str());
}

bool clang_experimental_DepGraphModuleLinkLibrary_isFramework(
CXDepGraphModuleLinkLibrary L) {
const DepGraphModuleLinkLibrary *Lib = unwrap(L);
return Lib->IsFramework;
}
5 changes: 5 additions & 0 deletions clang/tools/libclang/libclang.map
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,11 @@ LLVM_21 {
clang_experimental_DepScanFSCacheOutOfDateEntry_getCachedSize;
clang_experimental_DepScanFSCacheOutOfDateEntry_getActualSize;
clang_experimental_DepScanFSCacheOutOfDateEntrySet_disposeSet;
clang_experimental_DepGraphModule_getLinkLibrarySet;
clang_experimental_DepGraphModuleLinkLibrarySet_getSize;
clang_experimental_DepGraphModuleLinkLibrarySet_getLinkLibrary;
clang_experimental_DepGraphModuleLinkLibrary_getLibrary;
clang_experimental_DepGraphModuleLinkLibrary_isFramework;
};

# Example of how to add a new symbol version entry. If you do add a new symbol
Expand Down