Skip to content

Commit 543632d

Browse files
authored
Merge pull request #25202 from troughton/static-libraries-driver
[Driver] Add -static flag for generating static archives
2 parents f5fad1f + e5ea42d commit 543632d

File tree

14 files changed

+227
-25
lines changed

14 files changed

+227
-25
lines changed

include/swift/AST/DiagnosticsDriver.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ ERROR(error_expected_frontend_command,none,
6464
ERROR(error_cannot_specify__o_for_multiple_outputs,none,
6565
"cannot specify -o when generating multiple output files", ())
6666

67+
ERROR(error_static_emit_executable_disallowed,none,
68+
"-static may not be used with -emit-executable", ())
69+
6770
ERROR(error_unable_to_load_output_file_map, none,
6871
"unable to load output file map '%1': %0", (StringRef, StringRef))
6972

include/swift/Driver/Action.h

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ class Action {
4747
ModuleWrapJob,
4848
AutolinkExtractJob,
4949
REPLJob,
50-
LinkJob,
50+
DynamicLinkJob,
51+
StaticLinkJob,
5152
GenerateDSYMJob,
5253
VerifyDebugInfoJob,
5354
GeneratePCHJob,
@@ -305,21 +306,35 @@ class GeneratePCHJobAction : public JobAction {
305306
}
306307
};
307308

308-
class LinkJobAction : public JobAction {
309+
class DynamicLinkJobAction : public JobAction {
309310
virtual void anchor();
310311
LinkKind Kind;
311312

312313
public:
313-
LinkJobAction(ArrayRef<const Action *> Inputs, LinkKind K)
314-
: JobAction(Action::Kind::LinkJob, Inputs, file_types::TY_Image),
314+
DynamicLinkJobAction(ArrayRef<const Action *> Inputs, LinkKind K)
315+
: JobAction(Action::Kind::DynamicLinkJob, Inputs, file_types::TY_Image),
315316
Kind(K) {
316-
assert(Kind != LinkKind::None);
317+
assert(Kind != LinkKind::None && Kind != LinkKind::StaticLibrary);
317318
}
318319

319320
LinkKind getKind() const { return Kind; }
320321

321322
static bool classof(const Action *A) {
322-
return A->getKind() == Action::Kind::LinkJob;
323+
return A->getKind() == Action::Kind::DynamicLinkJob;
324+
}
325+
};
326+
327+
class StaticLinkJobAction : public JobAction {
328+
virtual void anchor();
329+
330+
public:
331+
StaticLinkJobAction(ArrayRef<const Action *> Inputs, LinkKind K)
332+
: JobAction(Action::Kind::StaticLinkJob, Inputs, file_types::TY_Image) {
333+
assert(K == LinkKind::StaticLibrary);
334+
}
335+
336+
static bool classof(const Action *A) {
337+
return A->getKind() == Action::Kind::StaticLinkJob;
323338
}
324339
};
325340

include/swift/Driver/ToolChain.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,10 @@ class ToolChain {
158158
virtual InvocationInfo
159159
constructInvocation(const AutolinkExtractJobAction &job,
160160
const JobContext &context) const;
161-
virtual InvocationInfo constructInvocation(const LinkJobAction &job,
161+
virtual InvocationInfo constructInvocation(const DynamicLinkJobAction &job,
162+
const JobContext &context) const;
163+
164+
virtual InvocationInfo constructInvocation(const StaticLinkJobAction &job,
162165
const JobContext &context) const;
163166

164167
/// Searches for the given executable in appropriate paths relative to the

include/swift/Driver/Util.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ namespace driver {
3434
enum class LinkKind {
3535
None,
3636
Executable,
37-
DynamicLibrary
37+
DynamicLibrary,
38+
StaticLibrary
3839
};
3940

4041
/// Used by a Job to request a "filelist": a file containing a list of all

include/swift/Option/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ def emit_objc_header_path : Separate<["-"], "emit-objc-header-path">,
376376
ArgumentIsPath]>,
377377
MetaVarName<"<path>">, HelpText<"Emit an Objective-C header file to <path>">;
378378

379+
def static : Flag<["-"], "static">,
380+
Flags<[FrontendOption, ModuleInterfaceOption, NoInteractiveOption]>,
381+
HelpText<"Make this module statically linkable and make the output of -emit-library a static library.">;
382+
379383
def import_cf_types : Flag<["-"], "import-cf-types">,
380384
Flags<[FrontendOption, HelpHidden]>,
381385
HelpText<"Recognize and import CF types as class types">;

lib/Driver/Action.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ const char *Action::getClassName(Kind AC) {
2828
case Kind::ModuleWrapJob: return "modulewrap";
2929
case Kind::AutolinkExtractJob: return "swift-autolink-extract";
3030
case Kind::REPLJob: return "repl";
31-
case Kind::LinkJob: return "link";
31+
case Kind::DynamicLinkJob: return "link";
32+
case Kind::StaticLinkJob: return "static-link";
3233
case Kind::GenerateDSYMJob: return "generate-dSYM";
3334
case Kind::VerifyDebugInfoJob: return "verify-debug-info";
3435
case Kind::GeneratePCHJob: return "generate-pch";
@@ -55,7 +56,9 @@ void AutolinkExtractJobAction::anchor() {}
5556

5657
void REPLJobAction::anchor() {}
5758

58-
void LinkJobAction::anchor() {}
59+
void DynamicLinkJobAction::anchor() {}
60+
61+
void StaticLinkJobAction::anchor() {}
5962

6063
void GenerateDSYMJobAction::anchor() {}
6164

lib/Driver/DarwinToolChains.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,8 @@ static bool wantsObjCRuntime(const llvm::Triple &triple) {
223223
}
224224

225225
ToolChain::InvocationInfo
226-
toolchains::Darwin::constructInvocation(const LinkJobAction &job,
227-
const JobContext &context) const
228-
{
226+
toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job,
227+
const JobContext &context) const {
229228
assert(context.Output.getPrimaryOutputType() == file_types::TY_Image &&
230229
"Invalid linker output type.");
231230

@@ -286,6 +285,8 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
286285
case LinkKind::DynamicLibrary:
287286
Arguments.push_back("-dylib");
288287
break;
288+
case LinkKind::StaticLibrary:
289+
llvm_unreachable("the dynamic linker cannot build static libraries");
289290
}
290291

291292
assert(Triple.isOSDarwin());
@@ -543,6 +544,41 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
543544
return II;
544545
}
545546

547+
548+
ToolChain::InvocationInfo
549+
toolchains::Darwin::constructInvocation(const StaticLinkJobAction &job,
550+
const JobContext &context) const {
551+
assert(context.Output.getPrimaryOutputType() == file_types::TY_Image &&
552+
"Invalid linker output type.");
553+
554+
// Configure the toolchain.
555+
const char *LibTool = "libtool";
556+
557+
InvocationInfo II = {LibTool};
558+
ArgStringList &Arguments = II.Arguments;
559+
560+
Arguments.push_back("-static");
561+
562+
if (context.shouldUseInputFileList()) {
563+
Arguments.push_back("-filelist");
564+
Arguments.push_back(context.getTemporaryFilePath("inputs", "LinkFileList"));
565+
II.FilelistInfos.push_back({Arguments.back(), file_types::TY_Object,
566+
FilelistInfo::WhichFiles::Input});
567+
} else {
568+
addPrimaryInputsOfType(Arguments, context.Inputs, context.Args,
569+
file_types::TY_Object);
570+
}
571+
572+
addInputsOfType(Arguments, context.InputActions, file_types::TY_Object);
573+
574+
Arguments.push_back("-o");
575+
576+
Arguments.push_back(
577+
context.Args.MakeArgString(context.Output.getPrimaryOutputFilename()));
578+
579+
return II;
580+
}
581+
546582
bool toolchains::Darwin::shouldStoreInvocationInDebugInfo() const {
547583
// This matches the behavior in Clang (see
548584
// clang/lib/driver/ToolChains/Darwin.cpp).

lib/Driver/Driver.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,8 @@ static bool maybeBuildingExecutable(const OutputInfo &OI,
12551255
return true;
12561256
case LinkKind::DynamicLibrary:
12571257
return false;
1258+
case LinkKind::StaticLibrary:
1259+
return false;
12581260
case LinkKind::None:
12591261
break;
12601262
}
@@ -1366,15 +1368,24 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args,
13661368

13671369
switch (OutputModeArg->getOption().getID()) {
13681370
case options::OPT_emit_executable:
1371+
if (Args.hasArg(options::OPT_static))
1372+
Diags.diagnose(SourceLoc(),
1373+
diag::error_static_emit_executable_disallowed);
1374+
13691375
OI.LinkAction = LinkKind::Executable;
13701376
OI.CompilerOutputType = file_types::TY_Object;
13711377
break;
13721378

13731379
case options::OPT_emit_library:
1374-
OI.LinkAction = LinkKind::DynamicLibrary;
1380+
OI.LinkAction = Args.hasArg(options::OPT_static) ?
1381+
LinkKind::StaticLibrary :
1382+
LinkKind::DynamicLibrary;
13751383
OI.CompilerOutputType = file_types::TY_Object;
13761384
break;
13771385

1386+
case options::OPT_static:
1387+
break;
1388+
13781389
case options::OPT_emit_object:
13791390
OI.CompilerOutputType = file_types::TY_Object;
13801391
break;
@@ -1550,7 +1561,8 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args,
15501561
OI.ModuleName = "REPL";
15511562
} else if (const Arg *A = Args.getLastArg(options::OPT_o)) {
15521563
OI.ModuleName = llvm::sys::path::stem(A->getValue());
1553-
if (OI.LinkAction == LinkKind::DynamicLibrary &&
1564+
if ((OI.LinkAction == LinkKind::DynamicLibrary ||
1565+
OI.LinkAction == LinkKind::StaticLibrary) &&
15541566
!llvm::sys::path::extension(A->getValue()).empty() &&
15551567
StringRef(OI.ModuleName).startswith("lib")) {
15561568
// Chop off a "lib" prefix if we're building a library.
@@ -1949,8 +1961,15 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
19491961
}
19501962

19511963
if (OI.shouldLink() && !AllLinkerInputs.empty()) {
1952-
auto *LinkAction = C.createAction<LinkJobAction>(AllLinkerInputs,
1953-
OI.LinkAction);
1964+
JobAction *LinkAction = nullptr;
1965+
1966+
if (OI.LinkAction == LinkKind::StaticLibrary) {
1967+
LinkAction = C.createAction<StaticLinkJobAction>(AllLinkerInputs,
1968+
OI.LinkAction);
1969+
} else {
1970+
LinkAction = C.createAction<DynamicLinkJobAction>(AllLinkerInputs,
1971+
OI.LinkAction);
1972+
}
19541973

19551974
// On ELF platforms there's no built in autolinking mechanism, so we
19561975
// pull the info we need from the .o files directly and pass them as an
@@ -2177,7 +2196,15 @@ static StringRef baseNameForImage(const JobAction *JA, const OutputInfo &OI,
21772196
StringRef BaseInput, StringRef BaseName) {
21782197
if (JA->size() == 1 && OI.ModuleNameIsFallback && BaseInput != "-")
21792198
return llvm::sys::path::stem(BaseInput);
2180-
auto link = dyn_cast<LinkJobAction>(JA);
2199+
2200+
if (auto link = dyn_cast<StaticLinkJobAction>(JA)) {
2201+
Buffer = "lib";
2202+
Buffer.append(BaseName);
2203+
Buffer.append(Triple.isOSWindows() ? ".lib" : ".a");
2204+
return Buffer.str();
2205+
}
2206+
2207+
auto link = dyn_cast<DynamicLinkJobAction>(JA);
21812208
if (!link)
21822209
return BaseName;
21832210
if (link->getKind() != LinkKind::DynamicLibrary)

lib/Driver/ToolChain.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ std::unique_ptr<Job> ToolChain::constructJob(
9999
CASE(BackendJob)
100100
CASE(MergeModuleJob)
101101
CASE(ModuleWrapJob)
102-
CASE(LinkJob)
102+
CASE(DynamicLinkJob)
103+
CASE(StaticLinkJob)
103104
CASE(GenerateDSYMJob)
104105
CASE(VerifyDebugInfoJob)
105106
CASE(GeneratePCHJob)

lib/Driver/ToolChains.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ static void addCommonFrontendArgs(const ToolChain &TC, const OutputInfo &OI,
208208
inputArgs.AddLastArg(arguments, options::OPT_warnings_as_errors);
209209
inputArgs.AddLastArg(arguments, options::OPT_sanitize_EQ);
210210
inputArgs.AddLastArg(arguments, options::OPT_sanitize_coverage_EQ);
211+
inputArgs.AddLastArg(arguments, options::OPT_static);
211212
inputArgs.AddLastArg(arguments, options::OPT_swift_version);
212213
inputArgs.AddLastArg(arguments, options::OPT_enforce_exclusivity_EQ);
213214
inputArgs.AddLastArg(arguments, options::OPT_stats_output_dir);
@@ -1090,11 +1091,17 @@ ToolChain::constructInvocation(const AutolinkExtractJobAction &job,
10901091
}
10911092

10921093
ToolChain::InvocationInfo
1093-
ToolChain::constructInvocation(const LinkJobAction &job,
1094+
ToolChain::constructInvocation(const DynamicLinkJobAction &job,
10941095
const JobContext &context) const {
10951096
llvm_unreachable("linking not implemented for this toolchain");
10961097
}
10971098

1099+
ToolChain::InvocationInfo
1100+
ToolChain::constructInvocation(const StaticLinkJobAction &job,
1101+
const JobContext &context) const {
1102+
llvm_unreachable("archiving not implemented for this toolchain");
1103+
}
1104+
10981105
void ToolChain::addPathEnvironmentVariableIfNeeded(
10991106
Job::EnvironmentVector &env, const char *name, const char *separator,
11001107
options::ID optionID, const ArgList &args, StringRef extraEntry) const {

0 commit comments

Comments
 (0)