mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
IRGen: internalize symbols with -static
This pipes the `-static` flag when building a static library into IRGen. This should have no impact on non-Windows targets as the usage of the information simply removes the `dllexport` attribute on the generated interfaces. This ensures that a library built with `-static` will not re-export its interfaces from the consumer. This is important to ensure that the consumer does not vend the API surface when it statically links a library. In conjunction with the removal of the force load symbol, this allows the generation of static libraries which may be linked against on Windows. However, a subsequent change is needed to ensure that the consumer does not mark the symbol as being imported from a foreign module (i.e. `dllimport`).
This commit is contained in:
@@ -377,6 +377,9 @@ public:
|
|||||||
|
|
||||||
unsigned InternalizeAtLink : 1;
|
unsigned InternalizeAtLink : 1;
|
||||||
|
|
||||||
|
/// Internalize symbols (static library) - do not export any public symbols.
|
||||||
|
unsigned InternalizeSymbols : 1;
|
||||||
|
|
||||||
/// Whether to avoid emitting zerofill globals as preallocated type metadata
|
/// Whether to avoid emitting zerofill globals as preallocated type metadata
|
||||||
/// and prototol conformance caches.
|
/// and prototol conformance caches.
|
||||||
unsigned NoPreallocatedInstantiationCaches : 1;
|
unsigned NoPreallocatedInstantiationCaches : 1;
|
||||||
@@ -443,7 +446,7 @@ public:
|
|||||||
DisableStandardSubstitutionsInReflectionMangling(false),
|
DisableStandardSubstitutionsInReflectionMangling(false),
|
||||||
EnableGlobalISel(false), VirtualFunctionElimination(false),
|
EnableGlobalISel(false), VirtualFunctionElimination(false),
|
||||||
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
|
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
|
||||||
InternalizeAtLink(false),
|
InternalizeAtLink(false), InternalizeSymbols(false),
|
||||||
NoPreallocatedInstantiationCaches(false),
|
NoPreallocatedInstantiationCaches(false),
|
||||||
CmdArgs(),
|
CmdArgs(),
|
||||||
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
|
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ class UniversalLinkageInfo {
|
|||||||
public:
|
public:
|
||||||
bool IsELFObject;
|
bool IsELFObject;
|
||||||
bool UseDLLStorage;
|
bool UseDLLStorage;
|
||||||
|
bool Internalize;
|
||||||
|
|
||||||
/// True iff are multiple llvm modules.
|
/// True iff are multiple llvm modules.
|
||||||
bool HasMultipleIGMs;
|
bool HasMultipleIGMs;
|
||||||
@@ -57,7 +58,7 @@ public:
|
|||||||
explicit UniversalLinkageInfo(IRGenModule &IGM);
|
explicit UniversalLinkageInfo(IRGenModule &IGM);
|
||||||
|
|
||||||
UniversalLinkageInfo(const llvm::Triple &triple, bool hasMultipleIGMs,
|
UniversalLinkageInfo(const llvm::Triple &triple, bool hasMultipleIGMs,
|
||||||
bool forcePublicDecls);
|
bool forcePublicDecls, bool isStaticLibrary);
|
||||||
|
|
||||||
/// In case of multiple llvm modules (in multi-threaded compilation) all
|
/// In case of multiple llvm modules (in multi-threaded compilation) all
|
||||||
/// private decls must be visible from other files.
|
/// private decls must be visible from other files.
|
||||||
|
|||||||
@@ -2190,6 +2190,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
|
|||||||
Opts.InternalizeAtLink = true;
|
Opts.InternalizeAtLink = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Opts.InternalizeSymbols = FrontendOpts.Static;
|
||||||
|
|
||||||
if (Args.hasArg(OPT_disable_preallocated_instantiation_caches)) {
|
if (Args.hasArg(OPT_disable_preallocated_instantiation_caches)) {
|
||||||
Opts.NoPreallocatedInstantiationCaches = true;
|
Opts.NoPreallocatedInstantiationCaches = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2020,7 +2020,9 @@ void IRGenModule::emitVTableStubs() {
|
|||||||
if (F.getEffectiveSymbolLinkage() == SILLinkage::Hidden)
|
if (F.getEffectiveSymbolLinkage() == SILLinkage::Hidden)
|
||||||
alias->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
alias->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||||
else
|
else
|
||||||
ApplyIRLinkage(IRLinkage::ExternalExport).to(alias);
|
ApplyIRLinkage(IRGen.Opts.InternalizeSymbols
|
||||||
|
? IRLinkage::Internal
|
||||||
|
: IRLinkage::ExternalExport).to(alias);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2090,7 +2092,8 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
|
|||||||
switch (linkage) {
|
switch (linkage) {
|
||||||
case SILLinkage::Public:
|
case SILLinkage::Public:
|
||||||
return {llvm::GlobalValue::ExternalLinkage, PublicDefinitionVisibility,
|
return {llvm::GlobalValue::ExternalLinkage, PublicDefinitionVisibility,
|
||||||
ExportedStorage};
|
info.Internalize ? llvm::GlobalValue::DefaultStorageClass
|
||||||
|
: ExportedStorage};
|
||||||
|
|
||||||
case SILLinkage::PublicNonABI:
|
case SILLinkage::PublicNonABI:
|
||||||
return isDefinition ? RESULT(WeakODR, Hidden, Default)
|
return isDefinition ? RESULT(WeakODR, Hidden, Default)
|
||||||
|
|||||||
@@ -1352,7 +1352,9 @@ void IRGenModule::emitSILProperty(SILProperty *prop) {
|
|||||||
TheTrivialPropertyDescriptor);
|
TheTrivialPropertyDescriptor);
|
||||||
ApplyIRLinkage({linkInfo.getLinkage(),
|
ApplyIRLinkage({linkInfo.getLinkage(),
|
||||||
linkInfo.getVisibility(),
|
linkInfo.getVisibility(),
|
||||||
llvm::GlobalValue::DLLExportStorageClass})
|
IRGen.Opts.InternalizeSymbols
|
||||||
|
? llvm::GlobalValue::DefaultStorageClass
|
||||||
|
: llvm::GlobalValue::DLLExportStorageClass})
|
||||||
.to(GA, linkInfo.isForDefinition());
|
.to(GA, linkInfo.isForDefinition());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1574,7 +1574,9 @@ static llvm::GlobalObject *createForceImportThunk(IRGenModule &IGM) {
|
|||||||
llvm::GlobalValue::LinkOnceODRLinkage, buf,
|
llvm::GlobalValue::LinkOnceODRLinkage, buf,
|
||||||
&IGM.Module);
|
&IGM.Module);
|
||||||
ForceImportThunk->setAttributes(IGM.constructInitialAttributes());
|
ForceImportThunk->setAttributes(IGM.constructInitialAttributes());
|
||||||
ApplyIRLinkage(IRLinkage::ExternalExport).to(ForceImportThunk);
|
ApplyIRLinkage(IGM.IRGen.Opts.InternalizeSymbols
|
||||||
|
? IRLinkage::Internal
|
||||||
|
: IRLinkage::ExternalExport).to(ForceImportThunk);
|
||||||
if (IGM.Triple.supportsCOMDAT())
|
if (IGM.Triple.supportsCOMDAT())
|
||||||
if (auto *GO = cast<llvm::GlobalObject>(ForceImportThunk))
|
if (auto *GO = cast<llvm::GlobalObject>(ForceImportThunk))
|
||||||
GO->setComdat(IGM.Module.getOrInsertComdat(ForceImportThunk->getName()));
|
GO->setComdat(IGM.Module.getOrInsertComdat(ForceImportThunk->getName()));
|
||||||
|
|||||||
@@ -80,14 +80,16 @@ bool swift::irgen::useDllStorage(const llvm::Triple &triple) {
|
|||||||
|
|
||||||
UniversalLinkageInfo::UniversalLinkageInfo(IRGenModule &IGM)
|
UniversalLinkageInfo::UniversalLinkageInfo(IRGenModule &IGM)
|
||||||
: UniversalLinkageInfo(IGM.Triple, IGM.IRGen.hasMultipleIGMs(),
|
: UniversalLinkageInfo(IGM.Triple, IGM.IRGen.hasMultipleIGMs(),
|
||||||
IGM.IRGen.Opts.ForcePublicLinkage) {}
|
IGM.IRGen.Opts.ForcePublicLinkage,
|
||||||
|
IGM.IRGen.Opts.InternalizeSymbols) {}
|
||||||
|
|
||||||
UniversalLinkageInfo::UniversalLinkageInfo(const llvm::Triple &triple,
|
UniversalLinkageInfo::UniversalLinkageInfo(const llvm::Triple &triple,
|
||||||
bool hasMultipleIGMs,
|
bool hasMultipleIGMs,
|
||||||
bool forcePublicDecls)
|
bool forcePublicDecls,
|
||||||
|
bool isStaticLibrary)
|
||||||
: IsELFObject(triple.isOSBinFormatELF()),
|
: IsELFObject(triple.isOSBinFormatELF()),
|
||||||
UseDLLStorage(useDllStorage(triple)), HasMultipleIGMs(hasMultipleIGMs),
|
UseDLLStorage(useDllStorage(triple)), HasMultipleIGMs(hasMultipleIGMs),
|
||||||
ForcePublicDecls(forcePublicDecls) {}
|
Internalize(isStaticLibrary), ForcePublicDecls(forcePublicDecls) {}
|
||||||
|
|
||||||
/// Mangle this entity into the given buffer.
|
/// Mangle this entity into the given buffer.
|
||||||
void LinkEntity::mangle(SmallVectorImpl<char> &buffer) const {
|
void LinkEntity::mangle(SmallVectorImpl<char> &buffer) const {
|
||||||
|
|||||||
@@ -173,7 +173,8 @@ public:
|
|||||||
ModuleDecl *swiftModule, const TBDGenOptions &opts,
|
ModuleDecl *swiftModule, const TBDGenOptions &opts,
|
||||||
APIRecorder &recorder)
|
APIRecorder &recorder)
|
||||||
: DataLayoutDescription(dataLayoutString),
|
: DataLayoutDescription(dataLayoutString),
|
||||||
UniversalLinkInfo(target, opts.HasMultipleIGMs, /*forcePublic*/ false),
|
UniversalLinkInfo(target, opts.HasMultipleIGMs, /*forcePublic*/ false,
|
||||||
|
/*static=*/false),
|
||||||
SwiftModule(swiftModule), Opts(opts), recorder(recorder),
|
SwiftModule(swiftModule), Opts(opts), recorder(recorder),
|
||||||
previousInstallNameMap(parsePreviousModuleInstallNameMap()) {}
|
previousInstallNameMap(parsePreviousModuleInstallNameMap()) {}
|
||||||
|
|
||||||
|
|||||||
76
test/IRGen/static-library.swift
Normal file
76
test/IRGen/static-library.swift
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
// RUN: %empty-directory(%t)
|
||||||
|
// RUN: %swiftc_driver_plain -target x86_64-unknown-windows-msvc -DLIBRARY -module-name Library -emit-library -static -autolink-force-load -module-link-name Library %s -o %t/library.lib -emit-module-path %t
|
||||||
|
// RUN: %swiftc_driver_plain -target x86_64-unknown-windows-msvc -DLIBRARY -module-name Library -emit-library -static -autolink-force-load -module-link-name Library %s -S -emit-ir -o - | %FileCheck -check-prefix CHECK-LIBRARY %s
|
||||||
|
// RUN: %swiftc_driver_plain -target x86_64-unknown-windows-msvc -I %t -emit-library -S -emit-ir -o - %s | %FileCheck -check-prefix CHECK-EMBEDDING %s
|
||||||
|
|
||||||
|
// REQUIRES: OS=windows-msvc
|
||||||
|
|
||||||
|
#if LIBRARY
|
||||||
|
|
||||||
|
// nominal type descriptor for Library.C
|
||||||
|
// CHECK-LIBRARY: @"$s7Library1CCMn" = constant
|
||||||
|
|
||||||
|
// nominal type descriptor for Library.S
|
||||||
|
// CHECK-LIBRARY: @"$s7Library1SVMn" = constant
|
||||||
|
|
||||||
|
// method descriptor for Library.C.method
|
||||||
|
// CHECK-LBRARY: @"$s7Library1CC6methodyyFTq" = alias
|
||||||
|
|
||||||
|
// type metadata for Library.C
|
||||||
|
// CHECK-LIBRARY: @"$s7Library1CCN" = alias
|
||||||
|
|
||||||
|
// type metadata for Library.S
|
||||||
|
// CHECK-LIBRARY: @"$s7Library1SVN" = alias
|
||||||
|
|
||||||
|
public func f() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Library.f() -> ()
|
||||||
|
// CHECK-LIBRARY: define swiftcc void @"$s7Library1fyyF"()
|
||||||
|
|
||||||
|
open class C {
|
||||||
|
var property: () -> () {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
open func method() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Library.C.method() -> ()
|
||||||
|
// CHECK-LIBRARY: define swiftcc void @"$s7Library1CC6methodyyF"(%T7Library1CC* swiftself %0)
|
||||||
|
|
||||||
|
// Library.C.deinit
|
||||||
|
// CHECK-LIBRARY: define swiftcc %swift.refcounted* @"$s7Library1CCfd"(%T7Library1CC* swiftself %0)
|
||||||
|
|
||||||
|
// Library.C.__deallocating_deinit
|
||||||
|
// CHECK-LIBRARY: define swiftcc void @"$s7Library1CCfD"(%T7Library1CC* swiftself %0)
|
||||||
|
|
||||||
|
// Library.C.__allocating_init() -> Library.C
|
||||||
|
// CHECK-LIBRARY: define swiftcc %T7Library1CC* @"$s7Library1CCACycfC"(%swift.type* swiftself %0)
|
||||||
|
|
||||||
|
public struct S {
|
||||||
|
var member: () -> Void = f
|
||||||
|
}
|
||||||
|
|
||||||
|
// variable initialization expression of Library.S.member : () -> ()
|
||||||
|
// CHECK-LIBRARY: define swiftcc { i8*, %swift.refcounted* } @"$s7Library1SV6memberyycvpfi"()
|
||||||
|
|
||||||
|
// type metadata accessor for Library.C
|
||||||
|
// CHECK-LIBRARY: define swiftcc %swift.metadata_response @"$s7Library1CCMa"(i64 %0)
|
||||||
|
|
||||||
|
// type metadata accessor for Library.S
|
||||||
|
// CHECK-LIBRARY: define swiftcc %swift.metadata_response @"$s7Library1SVMa"(i64 %0)
|
||||||
|
|
||||||
|
// CHECK-LIBRARY: define internal void @"_swift_FORCE_LOAD_$_Library"()
|
||||||
|
|
||||||
|
#else
|
||||||
|
import Library
|
||||||
|
func f() {
|
||||||
|
Library.f()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-EMBEDDING-NOT: @"_swift_FORCE_LOAD_$_Library"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
Reference in New Issue
Block a user