Skip to content

DependencyScan: track library style #78777

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

Merged
merged 1 commit into from
Feb 6, 2025
Merged
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
2 changes: 2 additions & 0 deletions include/swift-c/DependencyScan/DependencyScan.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ swiftscan_module_info_get_details(swiftscan_dependency_info_t info);
SWIFTSCAN_PUBLIC swiftscan_string_ref_t
swiftscan_link_library_info_get_link_name(
swiftscan_link_library_info_t info);
SWIFTSCAN_PUBLIC bool
swiftscan_link_library_info_get_is_static(swiftscan_link_library_info_t info);
SWIFTSCAN_PUBLIC bool swiftscan_link_library_info_get_is_framework(
swiftscan_link_library_info_t info);
SWIFTSCAN_PUBLIC bool swiftscan_link_library_info_get_should_force_load(
Expand Down
3 changes: 2 additions & 1 deletion include/swift/AST/IRGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "llvm/Support/VersionTuple.h"
#include <optional>
#include <string>
#include <tuple>
#include <vector>

namespace swift {
Expand Down Expand Up @@ -258,7 +259,7 @@ class IRGenOptions {
SmallVector<LinkLibrary, 4> LinkLibraries;

/// The public dependent libraries specified on the command line.
std::vector<std::string> PublicLinkLibraries;
std::vector<std::tuple<std::string, bool>> PublicLinkLibraries;

/// If non-empty, the (unmangled) name of a dummy symbol to emit that can be
/// used to force-load this module.
Expand Down
7 changes: 5 additions & 2 deletions include/swift/AST/LinkLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,19 @@ class LinkLibrary {
private:
std::string Name;
unsigned Kind : 1;
unsigned Static : 1;
unsigned ForceLoad : 1;

public:
LinkLibrary(StringRef N, LibraryKind K, bool forceLoad = false)
: Name(N), Kind(static_cast<unsigned>(K)), ForceLoad(forceLoad) {
LinkLibrary(StringRef N, LibraryKind K, bool Static, bool forceLoad = false)
: Name(N), Kind(static_cast<unsigned>(K)), Static(Static),
ForceLoad(forceLoad) {
assert(getKind() == K && "not enough bits for the kind");
}

LibraryKind getKind() const { return static_cast<LibraryKind>(Kind); }
StringRef getName() const { return Name; }
bool isStaticLibrary() const { return Static; }
bool shouldForceLoad() const { return ForceLoad; }
};

Expand Down
1 change: 1 addition & 0 deletions include/swift/DependencyScan/DependencyScanImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct swiftscan_dependency_info_s {

struct swiftscan_link_library_info_s {
swiftscan_string_ref_t name;
bool isStatic;
bool isFramework;
bool forceLoad;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ using llvm::BCVBR;
const unsigned char MODULE_DEPENDENCY_CACHE_FORMAT_SIGNATURE[] = {'I', 'M', 'D','C'};
const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MAJOR = 9;
/// Increment this on every change.
const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MINOR = 0;
const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MINOR = 1;

/// Various identifiers in this format will rely on having their strings mapped
/// using this ID.
Expand Down Expand Up @@ -148,12 +148,12 @@ using IdentifierArrayLayout =
// A record for a given link library node containing information
// required for the build system client to capture a requirement
// to link a given dependency library.
using LinkLibraryLayout =
BCRecordLayout<LINK_LIBRARY_NODE, // ID
IdentifierIDField, // libraryName
IsFrameworkField, // isFramework
IsForceLoadField // forceLoad
>;
using LinkLibraryLayout = BCRecordLayout<LINK_LIBRARY_NODE, // ID
IdentifierIDField, // libraryName
IsFrameworkField, // isFramework
IsStaticField, // isStatic
IsForceLoadField // forceLoad
>;
using LinkLibraryArrayLayout =
BCRecordLayout<LINK_LIBRARY_ARRAY_NODE, IdentifierIDArryField>;

Expand Down
4 changes: 2 additions & 2 deletions include/swift/Frontend/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@ class CompilerInvocation {
return ClangImporterOpts.ExtraArgs;
}

void addLinkLibrary(StringRef name, LibraryKind kind) {
IRGenOpts.LinkLibraries.push_back({name, kind});
void addLinkLibrary(StringRef name, LibraryKind kind, bool isStaticLibrary) {
IRGenOpts.LinkLibraries.emplace_back(name, kind, isStaticLibrary);
}

ArrayRef<LinkLibrary> getLinkLibraries() const {
Expand Down
3 changes: 2 additions & 1 deletion include/swift/Serialization/SerializationOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <set>
#include <string>
#include <tuple>
#include <vector>

namespace swift {
Expand Down Expand Up @@ -147,7 +148,7 @@ class SerializationOptions {
uint64_t getSize() const { return Size; }
};
ArrayRef<FileDependency> Dependencies;
ArrayRef<std::string> PublicDependentLibraries;
ArrayRef<std::tuple<std::string, bool>> PublicDependentLibraries;

bool AutolinkForceLoad = false;
bool SerializeAllSIL = false;
Expand Down
60 changes: 30 additions & 30 deletions lib/AST/ModuleDependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,24 +490,33 @@ swift::dependencies::checkImportNotTautological(const ImportPath::Module moduleP
return false;
}

void
swift::dependencies::registerCxxInteropLibraries(
const llvm::Triple &Target,
StringRef mainModuleName,
bool hasStaticCxx, bool hasStaticCxxStdlib, CXXStdlibKind cxxStdlibKind,
std::function<void(const LinkLibrary&)> RegistrationCallback) {
if (cxxStdlibKind == CXXStdlibKind::Libcxx)
RegistrationCallback(LinkLibrary("c++", LibraryKind::Library));
else if (cxxStdlibKind == CXXStdlibKind::Libstdcxx)
RegistrationCallback(LinkLibrary("stdc++", LibraryKind::Library));
void swift::dependencies::registerCxxInteropLibraries(
const llvm::Triple &Target, StringRef mainModuleName, bool hasStaticCxx,
bool hasStaticCxxStdlib, CXXStdlibKind cxxStdlibKind,
std::function<void(const LinkLibrary &)> RegistrationCallback) {

switch (cxxStdlibKind) {
case CXXStdlibKind::Libcxx:
RegistrationCallback(
LinkLibrary{"c++", LibraryKind::Library, /*static=*/false});
break;
case CXXStdlibKind::Libstdcxx:
RegistrationCallback(
LinkLibrary{"stdc++", LibraryKind::Library, /*static=*/false});
break;
case CXXStdlibKind::Msvcprt:
// FIXME: should we be explicitly linking in msvcprt or will the module do
// so?
break;
case CXXStdlibKind::Unknown:
// FIXME: we should probably emit a warning or a note here.
break;
}

// Do not try to link Cxx with itself.
if (mainModuleName != CXX_MODULE_NAME) {
RegistrationCallback(LinkLibrary(Target.isOSWindows() && hasStaticCxx
? "libswiftCxx"
: "swiftCxx",
LibraryKind::Library));
}
if (mainModuleName != CXX_MODULE_NAME)
RegistrationCallback(
LinkLibrary{"swiftCxx", LibraryKind::Library, hasStaticCxx});

// Do not try to link CxxStdlib with the C++ standard library, Cxx or
// itself.
Expand All @@ -516,19 +525,9 @@ swift::dependencies::registerCxxInteropLibraries(
return mainModuleName == Name;
})) {
// Only link with CxxStdlib on platforms where the overlay is available.
switch (Target.getOS()) {
case llvm::Triple::Win32: {
RegistrationCallback(
LinkLibrary(hasStaticCxxStdlib ? "libswiftCxxStdlib" : "swiftCxxStdlib",
LibraryKind::Library));
break;
}
default:
if (Target.isOSDarwin() || Target.isOSLinux())
RegistrationCallback(LinkLibrary("swiftCxxStdlib",
LibraryKind::Library));
break;
}
if (Target.isOSDarwin() || Target.isOSLinux() || Target.isOSWindows())
RegistrationCallback(LinkLibrary{"swiftCxxStdlib", LibraryKind::Library,
hasStaticCxxStdlib});
}
}

Expand Down Expand Up @@ -556,7 +555,8 @@ swift::dependencies::registerBackDeployLibraries(
if (*compatibilityVersion > version)
return;

RegistrationCallback({libraryName, LibraryKind::Library, forceLoad});
RegistrationCallback(
{libraryName, LibraryKind::Library, /*static=*/true, forceLoad});
};

#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
Expand Down
14 changes: 5 additions & 9 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4082,15 +4082,11 @@ void ClangModuleUnit::collectLinkLibraries(
if (clangModule->UseExportAsModuleLinkName)
return;

for (auto clangLinkLib : clangModule->LinkLibraries) {
LibraryKind kind;
if (clangLinkLib.IsFramework)
kind = LibraryKind::Framework;
else
kind = LibraryKind::Library;

callback(LinkLibrary(clangLinkLib.Library, kind));
}
for (auto clangLinkLib : clangModule->LinkLibraries)
callback(LinkLibrary{clangLinkLib.Library,
clangLinkLib.IsFramework ? LibraryKind::Framework
: LibraryKind::Library,
/*static=*/false});
}

StringRef ClangModuleUnit::getFilename() const {
Expand Down
7 changes: 4 additions & 3 deletions lib/ClangImporter/ClangModuleDependencyScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,10 @@ ModuleDependencyVector ClangImporter::bridgeClangModuleDependencies(

std::vector<LinkLibrary> LinkLibraries;
for (const auto &ll : clangModuleDep.LinkLibraries)
LinkLibraries.push_back(
{ll.Library,
ll.IsFramework ? LibraryKind::Framework : LibraryKind::Library});
LinkLibraries.emplace_back(
ll.Library,
ll.IsFramework ? LibraryKind::Framework : LibraryKind::Library,
/*static=*/false);

// Module-level dependencies.
llvm::StringSet<> alreadyAddedModules;
Expand Down
4 changes: 4 additions & 0 deletions lib/DependencyScan/DependencyScanJSON.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ void writeLinkLibraries(llvm::raw_ostream &out,
writeJSONValue(out, llInfo.name, indentLevel);
out << ",\n";
out.indent(entryIndentLevel);
out << "\"isStatic\": ";
writeJSONValue(out, llInfo.isStatic, entryIndentLevel);
out << ",\n";
out.indent(entryIndentLevel);
out << "\"isFramework\": ";
writeJSONValue(out, llInfo.isFramework, entryIndentLevel);
out << ",\n";
Expand Down
18 changes: 9 additions & 9 deletions lib/DependencyScan/ModuleDependencyCacheSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,17 +355,18 @@ bool ModuleDependenciesCacheDeserializer::readGraph(

case LINK_LIBRARY_NODE: {
unsigned libraryIdentifierID;
bool isFramework, shouldForceLoad;
bool isFramework, isStatic, shouldForceLoad;
LinkLibraryLayout::readRecord(Scratch, libraryIdentifierID, isFramework,
shouldForceLoad);
isStatic, shouldForceLoad);
auto libraryIdentifier = getIdentifier(libraryIdentifierID);
if (!libraryIdentifier)
llvm::report_fatal_error("Bad link library identifier");

LinkLibraries.push_back(LinkLibrary(libraryIdentifier.value(),
isFramework ? LibraryKind::Framework
: LibraryKind::Library,
shouldForceLoad));
LinkLibraries.emplace_back(
libraryIdentifier.value(),
isFramework ? LibraryKind::Framework
: LibraryKind::Library,
isStatic, shouldForceLoad);
break;
}

Expand Down Expand Up @@ -1302,13 +1303,12 @@ void ModuleDependenciesCacheSerializer::writeLinkLibraries(
unsigned ModuleDependenciesCacheSerializer::writeLinkLibraryInfos(
const ModuleDependencyInfo &dependencyInfo) {
using namespace graph_block;
for (auto &linkLibrary : dependencyInfo.getLinkLibraries()) {
for (auto &linkLibrary : dependencyInfo.getLinkLibraries())
LinkLibraryLayout::emitRecord(
Out, ScratchRecord, AbbrCodes[LinkLibraryLayout::Code],
getIdentifier(linkLibrary.getName().str()),
linkLibrary.getKind() == LibraryKind::Framework,
linkLibrary.shouldForceLoad());
}
linkLibrary.isStaticLibrary(), linkLibrary.shouldForceLoad());
return dependencyInfo.getLinkLibraries().size();
}

Expand Down
3 changes: 2 additions & 1 deletion lib/DependencyScan/ScanDependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,7 @@ generateFullDependencyGraph(const CompilerInstance &instance,
const auto &ll = linkLibraries[i];
swiftscan_link_library_info_s *llInfo = new swiftscan_link_library_info_s;
llInfo->name = create_clone(ll.getName().str().c_str());
llInfo->isStatic = ll.isStaticLibrary();
llInfo->isFramework = ll.getKind() == LibraryKind::Framework;
llInfo->forceLoad = ll.shouldForceLoad();
linkLibrarySet->link_libraries[i] = llInfo;
Expand Down Expand Up @@ -1239,7 +1240,7 @@ static void resolveImplicitLinkLibraries(const CompilerInstance &instance,
};

if (langOpts.EnableObjCInterop)
addLinkLibrary({"objc", LibraryKind::Library});
addLinkLibrary(LinkLibrary{"objc", LibraryKind::Library, /*static=*/false});

if (langOpts.EnableCXXInterop) {
auto OptionalCxxDep = cache.findDependency(CXX_MODULE_NAME);
Expand Down
11 changes: 6 additions & 5 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3211,7 +3211,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
llvm_unreachable("Unknown LinkLibrary option kind");
}

Opts.LinkLibraries.push_back(LinkLibrary(A->getValue(), Kind));
Opts.LinkLibraries.emplace_back(
A->getValue(), Kind, /*static=*/false);
}

if (auto valueNames = Args.getLastArg(OPT_disable_llvm_value_names,
Expand Down Expand Up @@ -3441,11 +3442,11 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
}

for (const auto &Lib : Args.getAllArgValues(options::OPT_autolink_library))
Opts.LinkLibraries.push_back(LinkLibrary(Lib, LibraryKind::Library));
Opts.LinkLibraries.emplace_back(
Lib, LibraryKind::Library, /*static=*/false);

for (const auto &Lib : Args.getAllArgValues(options::OPT_public_autolink_library)) {
Opts.PublicLinkLibraries.push_back(Lib);
}
for (const auto &Lib : Args.getAllArgValues(options::OPT_public_autolink_library))
Opts.PublicLinkLibraries.push_back(std::make_tuple(Lib, /*static=*/false));

if (const Arg *A = Args.getLastArg(OPT_type_info_dump_filter_EQ)) {
StringRef mode(A->getValue());
Expand Down
24 changes: 14 additions & 10 deletions lib/IRGen/IRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1581,32 +1581,35 @@ swift::irgen::encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
}

llvm::SmallString<32> getTargetDependentLibraryOption(const llvm::Triple &T,
StringRef library) {
LinkLibrary library) {
llvm::SmallString<32> buffer;
StringRef name = library.getName();

if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {
bool quote = library.contains(' ');
bool quote = name.contains(' ');

buffer += "/DEFAULTLIB:";
if (quote)
buffer += '"';
buffer += library;
if (!library.ends_with_insensitive(".lib"))
if (library.isStaticLibrary() && !name.starts_with_insensitive("lib"))
buffer += "lib";
buffer += name;
if (!name.ends_with_insensitive(".lib"))
buffer += ".lib";
if (quote)
buffer += '"';
} else if (T.isPS4()) {
bool quote = library.contains(' ');
bool quote = name.contains(' ');

buffer += "\01";
if (quote)
buffer += '"';
buffer += library;
buffer += name;
if (quote)
buffer += '"';
} else {
buffer += "-l";
buffer += library;
buffer += name;
}

return buffer;
Expand Down Expand Up @@ -1686,7 +1689,8 @@ void IRGenModule::addLinkLibraries() {
});

if (ObjCInterop)
registerLinkLibrary(LinkLibrary("objc", LibraryKind::Library));
registerLinkLibrary(
LinkLibrary{"objc", LibraryKind::Library, /*static=*/false});

// If C++ interop is enabled, add -lc++ on Darwin and -lstdc++ on linux.
// Also link with C++ bridging utility module (Cxx) and C++ stdlib overlay
Expand Down Expand Up @@ -1817,7 +1821,7 @@ void AutolinkKind::collectEntriesFromLibraries(
switch (linkLib.getKind()) {
case LibraryKind::Library: {
llvm::SmallString<32> opt =
getTargetDependentLibraryOption(IGM.Triple, linkLib.getName());
getTargetDependentLibraryOption(IGM.Triple, linkLib);
Entries.insert(llvm::MDNode::get(ctx, llvm::MDString::get(ctx, opt)));
continue;
}
Expand All @@ -1838,7 +1842,7 @@ void AutolinkKind::collectEntriesFromLibraries(
switch (linkLib.getKind()) {
case LibraryKind::Library: {
llvm::SmallString<32> opt =
getTargetDependentLibraryOption(IGM.Triple, linkLib.getName());
getTargetDependentLibraryOption(IGM.Triple, linkLib);
Entries.insert(llvm::MDNode::get(ctx, llvm::MDString::get(ctx, opt)));
continue;
}
Expand Down
Loading