-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Driver] Add -static flag for generating static archives #25202
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
[Driver] Add -static flag for generating static archives #25202
Conversation
include/swift/Driver/Action.h
Outdated
@@ -48,6 +48,7 @@ class Action { | |||
AutolinkExtractJob, | |||
REPLJob, | |||
LinkJob, | |||
ArchiveJob, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to get @jrose-apple's opinion on naming these: DyamicLinkJob
and StaticLinkJob
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think I like @compnerd's names better (sans typo).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing it in a separate commit (but still the same PR) might be nice for reviewing purposes, but not necessary.
ArgStringList Arguments; | ||
|
||
// Configure the toolchain. | ||
const char *LibTool = "libtool"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to use ar
to do the operation. The only time that libtool
is really required is for fat libraries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really have an opinion here, but from the previous review: #25088 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented on that - I think that we can safely get away with it with llvm-ar
at least
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented against it. :-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that we can get away with it using the stock Xcode tools as well (do we really care about the original AT&T Unix?).
lib/Driver/DarwinToolChains.cpp
Outdated
@@ -284,6 +284,8 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job, | |||
case LinkKind::DynamicLibrary: | |||
Arguments.push_back("-dylib"); | |||
break; | |||
case LinkKind::StaticLibrary: | |||
llvm_unreachable("invalid link kind"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than "invalid link kind" can you clarify that cannot perform archiving with the dynamic linker?
lib/Driver/Driver.cpp
Outdated
@@ -2177,6 +2196,19 @@ static StringRef baseNameForImage(const JobAction *JA, const OutputInfo &OI, | |||
StringRef BaseInput, StringRef BaseName) { | |||
if (JA->size() == 1 && OI.ModuleNameIsFallback && BaseInput != "-") | |||
return llvm::sys::path::stem(BaseInput); | |||
|
|||
if (auto link = dyn_cast<ArchiveJobAction>(JA)) { | |||
Buffer = Triple.isOSWindows() ? "" : "lib"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, please prepend lib
on Windows for the static archives.
lib/Driver/Driver.cpp
Outdated
if (Triple.isOSWindows()) | ||
Buffer.append(".lib"); | ||
else | ||
Buffer.append(".a"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just use a ternary here.
lib/Driver/UnixToolChains.cpp
Outdated
} | ||
} | ||
|
||
if (AR == nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can combine this with the previous clause with an else
:
if (const char *ar = llvm::sys::findProgramByName("llvm-ar", {toolchainPath}))
Arguments.push_back(context.Args.MakeArgString(ar));
else if (const char *ar = llvm::sys::findProgramByName("ar", {toolchainPath}))
Arguments.push_back(context.Args.MakeArgString(ar));
lib/Driver/UnixToolChains.cpp
Outdated
addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); | ||
|
||
InvocationInfo II{AR, Arguments}; | ||
II.allowsResponseFiles = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mmm I don't think that the traditional archiver permits response files. This should be equivalent to whether llvm-ar
is in use.
@@ -61,6 +61,8 @@ toolchains::Windows::constructInvocation(const LinkJobAction &job, | |||
case LinkKind::DynamicLibrary: | |||
Arguments.push_back("-shared"); | |||
break; | |||
case LinkKind::StaticLibrary: | |||
llvm_unreachable("invalid link kind"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to Darwin and Linux cases
lib/Driver/WindowsToolChains.cpp
Outdated
ArgStringList Arguments; | ||
|
||
// Configure the toolchain. | ||
const char *Lib = "lib"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use llvm-ar
if available, otherwise fall back to lld-link
(lld-link -lib
), otherwise try lib
. I don't think that we need to bother with link /LIB
as a means of invoking the librarian (lib
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems a lot of complexity – three tools with different invocations. I assume you want llvm-ar
and lld-link
for cross-compilation, so would it be enough to just pick one of those and say it's required for cross-compilation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to depend on lld-link
yet. Until we have swift-lld created and tracking, please do not depend on lld-link
. However, lld-link
and link
should be compatible enough, and link -lib
is the same as lib.exe
. So if you want to just use link to invoke the librarian, I am fine with that for Windows. You can use either lld-link
or link
then to invoke lib
.
test/Driver/static-archive.swift
Outdated
// INFERRED_NAME_DARWIN: libtool -static | ||
// INFERRED_NAME_DARWIN: -o libARCHIVER.a | ||
// INFERRED_NAME_LINUX: libARCHIVER.a | ||
// INFERRED_NAME_WINDOWS: ARCHIVER.lib |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test case for the invalid combination (-emit-executable -static
) as well as tests for the fallback path using mocked toolchains.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you clarify what you mean by "tests for the fallback path using mocked toolchains", or point to existing similar tests? I assume you mean ensure that we use the correct tools for e.g. lld-link
, but I can't see where that's actually tested for the dynamic linker path – there's a line referencing config.link
in lit.cfg
but I'm not sure how that feeds into the tests.
cf350b2
to
4f391b4
Compare
lib/Driver/DarwinToolChains.cpp
Outdated
context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); | ||
|
||
InvocationInfo II{LibTool, Arguments}; | ||
II.allowsResponseFiles = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think libtool does allow response files. It does have a form of filelist, though, which you could borrow from the dynamic linking logic on Darwin.
lib/Driver/Driver.cpp
Outdated
@@ -1550,7 +1561,8 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args, | |||
OI.ModuleName = "REPL"; | |||
} else if (const Arg *A = Args.getLastArg(options::OPT_o)) { | |||
OI.ModuleName = llvm::sys::path::stem(A->getValue()); | |||
if (OI.LinkAction == LinkKind::DynamicLibrary && | |||
if ((OI.LinkAction == LinkKind::DynamicLibrary || | |||
OI.LinkAction == LinkKind::StaticLibrary) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: indentation should align by the open-paren.
19585e2
to
78b593f
Compare
…kJob # Conflicts: # lib/Driver/DarwinToolChains.cpp
78b593f
to
e5ea42d
Compare
I've removed the parts of this PR which used non-system-default linkers. @compnerd, I know that won't meet your needs, but it's probably best to get the uncontroversial parts of this PR in before dealing with the complexity of customising the choice of linker. Provided this looks okay with you, @jrose-apple, this should be okay to merge. (I've rebased off master but can't build locally since I don't have Catalina installed – hopefully all the tests still pass CI.) |
I'll take a look soon, but note that you shouldn't need Catalina installed to build, just Xcode 11. |
@swift-ci Please test |
@compnerd, are you okay with this base thing going in, and we can discuss libtool/ar/llvm-ar later? |
@jrose-apple - okay, lets do that. At least we have a starting point then to make improvements. |
Add a
-static
flag to the driver that, when combined with-emit-library
, generates a static library using the platform archiver.In the future, this
-static
flag will also be used on Windows to determine whether a Swift module should have DLLImport linkage applied.