[llvm] r349096 - [gn build] Add infrastructure to create symlinks and use it to create lld's symlinks
Nico Weber via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 13 16:16:33 PST 2018
Author: nico
Date: Thu Dec 13 16:16:33 2018
New Revision: 349096
URL: http://llvm.org/viewvc/llvm-project?rev=349096&view=rev
Log:
[gn build] Add infrastructure to create symlinks and use it to create lld's symlinks
This is slightly involved, see the comments in the code.
The GN build now builds a functional lld!
Differential Revision: https://reviews.llvm.org/D55606
Added:
llvm/trunk/utils/gn/build/symlink_or_copy.gni
llvm/trunk/utils/gn/build/symlink_or_copy.py
Modified:
llvm/trunk/utils/gn/secondary/BUILD.gn
llvm/trunk/utils/gn/secondary/lld/tools/lld/BUILD.gn
Added: llvm/trunk/utils/gn/build/symlink_or_copy.gni
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/gn/build/symlink_or_copy.gni?rev=349096&view=auto
==============================================================================
--- llvm/trunk/utils/gn/build/symlink_or_copy.gni (added)
+++ llvm/trunk/utils/gn/build/symlink_or_copy.gni Thu Dec 13 16:16:33 2018
@@ -0,0 +1,24 @@
+# Creates a symlink (or, on Windows, copies).
+# Args:
+# source: Path to link to.
+# output: Where to create the symlink.
+template("symlink_or_copy") {
+ action(target_name) {
+ forward_variables_from(invoker, [ "deps" ])
+
+ # Make a stamp file the output to work around
+ # https://github.com/ninja-build/ninja/issues/1186
+ stamp =
+ "$target_gen_dir/" + get_path_info(invoker.output, "file") + ".stamp"
+ outputs = [
+ stamp,
+ ]
+ script = "//llvm/utils/gn/build/symlink_or_copy.py"
+ args = [
+ "--stamp",
+ rebase_path(stamp, root_out_dir),
+ invoker.source,
+ rebase_path(invoker.output, root_out_dir),
+ ]
+ }
+}
Added: llvm/trunk/utils/gn/build/symlink_or_copy.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/gn/build/symlink_or_copy.py?rev=349096&view=auto
==============================================================================
--- llvm/trunk/utils/gn/build/symlink_or_copy.py (added)
+++ llvm/trunk/utils/gn/build/symlink_or_copy.py Thu Dec 13 16:16:33 2018
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+
+"""Symlinks, or on Windows copies, an existing file to a second location.
+
+Overwrites the target location if it exists.
+Updates the mtime on a stamp file when done."""
+
+import argparse
+import errno
+import os
+import sys
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('--stamp', required=True,
+ help='name of a file whose mtime is updated on run')
+ parser.add_argument('source')
+ parser.add_argument('output')
+ args = parser.parse_args()
+
+ # FIXME: This should not check the host platform but the target platform
+ # (which needs to be passed in as an arg), for cross builds.
+ if sys.platform != 'win32':
+ try:
+ os.symlink(args.source, args.output)
+ except OSError as e:
+ if e.errno == errno.EEXIST:
+ os.remove(args.output)
+ os.symlink(args.source, args.output)
+ else:
+ raise
+ else:
+ import shutil
+ output = args.output + ".exe"
+ source = args.source + ".exe"
+ shutil.copyfile(os.path.join(os.path.dirname(output), source), output)
+
+ open(args.stamp, 'w') # Update mtime on stamp file.
+
+
+if __name__ == '__main__':
+ sys.exit(main())
Modified: llvm/trunk/utils/gn/secondary/BUILD.gn
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/gn/secondary/BUILD.gn?rev=349096&r1=349095&r2=349096&view=diff
==============================================================================
--- llvm/trunk/utils/gn/secondary/BUILD.gn (original)
+++ llvm/trunk/utils/gn/secondary/BUILD.gn Thu Dec 13 16:16:33 2018
@@ -1,11 +1,40 @@
group("default") {
deps = [
- "//lld/tools/lld",
+ ":lld",
"//llvm/tools/llc",
"//llvm/tools/llvm-undname",
]
}
+# Symlink handling.
+# On POSIX, symlinks to the target can be created before the target exist,
+# and the target can depend on the symlink targets, so that building the
+# target ensures the symlinks exist.
+# However, symlinks didn't exist on Windows until recently, so there the
+# binary needs to be copied -- which requires it to exist. So the symlink step
+# needs to run after the target that creates the binary.
+# In the cmake build, this is done via a "postbuild" on the target, which just
+# tacks on "&& copy out.exe out2.exe" to the link command.
+# GN doesn't have a way to express postbuild commands. It could probably be
+# emulated by having the link command in the toolchain be a wrapper script that
+# reads a ".symlinks" file next to the target, and have an action write that
+# and make the target depend on that, but then every single link has to use the
+# wrapper (unless we do further acrobatics to use a different toolchain for
+# targets that need symlinks) even though most links don't need symlinks.
+# Instead, have a top-level target for each target that needs symlinks, and
+# make that depend on the symlinks. Then the symlinks can depend on the
+# executable. This has the effect that `ninja lld` builds lld and then creates
+# symlinks (via this target), while `ninja bin/lld` only builds lld and doesn't
+# update symlinks (in particular, on Windows it doesn't copy the new lld to its
+# new locations); also `ninja lld-link` will build lld and copy it (on Windows)
+# to lld-link, but it won't copy it to ld.lld.
+# That seems simpler, more explicit, and good enough.
+group("lld") {
+ deps = [
+ "//lld/tools/lld:symlinks",
+ ]
+}
+
# A pool called "console" in the root BUILD.gn is magic and represents ninja's
# built-in console pool. (Requires a GN with `gn --version` >= 552353.)
pool("console") {
Modified: llvm/trunk/utils/gn/secondary/lld/tools/lld/BUILD.gn
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/gn/secondary/lld/tools/lld/BUILD.gn?rev=349096&r1=349095&r2=349096&view=diff
==============================================================================
--- llvm/trunk/utils/gn/secondary/lld/tools/lld/BUILD.gn (original)
+++ llvm/trunk/utils/gn/secondary/lld/tools/lld/BUILD.gn Thu Dec 13 16:16:33 2018
@@ -1,4 +1,28 @@
-# FIXME: Set up symlinks pointing to lld.
+import("//llvm/utils/gn/build/symlink_or_copy.gni")
+
+symlinks = [
+ "lld-link",
+ "ld.lld",
+ "ld64.lld",
+ "wasm-ld",
+]
+foreach(target, symlinks) {
+ symlink_or_copy(target) {
+ deps = [
+ ":lld",
+ ]
+ source = "lld"
+ output = "$root_out_dir/bin/$target"
+ }
+}
+
+# //:lld depends on this symlink target, see comment in //BUILD.gn.
+group("symlinks") {
+ deps = []
+ foreach(target, symlinks) {
+ deps += [ ":$target" ]
+ }
+}
executable("lld") {
configs += [ "//llvm/utils/gn/build:lld_code" ]
More information about the llvm-commits
mailing list