[llvm] fc96961 - [gn build] Use .export files

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Thu May 20 11:50:18 PDT 2021


Author: Nico Weber
Date: 2021-05-20T14:48:12-04:00
New Revision: fc9696130c8950fd0fbe2d4d571aa12c62f62a7a

URL: https://github.com/llvm/llvm-project/commit/fc9696130c8950fd0fbe2d4d571aa12c62f62a7a
DIFF: https://github.com/llvm/llvm-project/commit/fc9696130c8950fd0fbe2d4d571aa12c62f62a7a.diff

LOG: [gn build] Use .export files

Just fixing an old TODO, no dramatic behavior change.

Differential Revision: https://reviews.llvm.org/D102843

Added: 
    llvm/utils/gn/build/symbol_exports.gni
    llvm/utils/gn/build/symbol_exports.py

Modified: 
    llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn
    llvm/utils/gn/secondary/llvm/lib/Transforms/Hello/BUILD.gn
    llvm/utils/gn/secondary/llvm/tools/bugpoint-passes/BUILD.gn
    llvm/utils/gn/secondary/llvm/tools/lto/BUILD.gn

Removed: 
    


################################################################################
diff  --git a/llvm/utils/gn/build/symbol_exports.gni b/llvm/utils/gn/build/symbol_exports.gni
new file mode 100644
index 0000000000000..ed0e7df560e0b
--- /dev/null
+++ b/llvm/utils/gn/build/symbol_exports.gni
@@ -0,0 +1,59 @@
+# This file defines a template for using .export files.
+#
+# Parameters:
+#   exports_file (required)
+#       Path of the .exports file to use.
+#
+# Example use:
+#   symbol_exports("my_exports") {
+#     exports_file = "//foo/bar/my.exports"
+#   }
+#   ...
+#   shared_library("my_target") {
+#     deps = [ ":my_exports" ]  # Adds correct ldflags.
+#     ...
+#   }
+
+# Corresponds to add_llvm_symbol_exports() in the CMake build.
+template("symbol_exports") {
+  # Create a platform-appropriate name for the temporary file.
+  linker_file = get_path_info(invoker.exports_file, "name")
+  if (current_os == "mac") {
+    linker_file = linker_file + "_symbols.txt"
+  } else if (current_os == "win") {
+    linker_file = linker_file + ".def"
+  } else {
+    linker_file = linker_file + ".script"
+  }
+  linker_file = "$target_gen_dir/$linker_file"
+  rebased_linker_file = rebase_path(linker_file, root_build_dir)
+
+  config_name = "${target_name}_config"
+  config(config_name) {
+    # FIXME: With this setup, targets are not relinked automatically
+    # when the input exports file is touched but nothing else changes.
+    # https://groups.google.com/a/chromium.org/g/gn-dev/c/sN09GYS1ufE
+    visibility = [ ":$target_name" ]
+    if (current_os == "mac") {
+      ldflags = [ "-Wl,-exported_symbols_list,$rebased_linker_file" ]
+    } else if (current_os == "win") {
+      ldflags = [ "/DEF:$rebased_linker_file" ]
+    } else {
+      ldflags = [ "-Wl,--version-script,$rebased_linker_file" ]
+    }
+  }
+
+  action(target_name) {
+    script = "//llvm/utils/gn/build/symbol_exports.py"
+    inputs = [ invoker.exports_file ]
+    outputs = [ linker_file ]
+    args = [
+      "--format=" + current_os,
+      rebase_path(inputs[0], root_build_dir),
+      rebased_linker_file,
+    ]
+
+    # Let targets depending on this receive the right ldflags.
+    public_configs = [ ":$config_name" ]
+  }
+}

diff  --git a/llvm/utils/gn/build/symbol_exports.py b/llvm/utils/gn/build/symbol_exports.py
new file mode 100644
index 0000000000000..9d9c798db2727
--- /dev/null
+++ b/llvm/utils/gn/build/symbol_exports.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+
+"""Converts a .exports file to a format consumable by linkers.
+
+An .exports file is a file with one exported symbol per line.
+This script converts a .exports file into a format that linkers
+can understand:
+- It prepends a `_` to each line for use with -exported_symbols_list for Darwin
+- It writes a .def file for use with /DEF: for Windows
+- It writes a linker script for use with --version-script elsewhere
+"""
+
+import argparse
+import sys
+
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument('--format', required=True,
+                        choices=('linux','mac','win'))
+    parser.add_argument('source')
+    parser.add_argument('output')
+    args = parser.parse_args()
+
+    symbols = open(args.source).readlines()
+
+    if args.format == 'linux':
+      output_lines = (['FOO {\n',
+                       '  global:\n',] +
+                      ['    %s;\n' % s.rstrip() for s in symbols] +
+                      ['  local: *;\n',
+                       '}\n'])
+    elif args.format == 'mac':
+      output_lines = ['_' + s for s in symbols]
+    else:
+      assert args.format == 'win'
+      output_lines = ['EXPORTS\n'] + ['  ' + s for s in symbols]
+
+    open(args.output, 'w').writelines(output_lines)
+
+
+if __name__ == '__main__':
+    sys.exit(main())

diff  --git a/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn b/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn
index d0cddcfaad048..e72af8fbc7a48 100644
--- a/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn
+++ b/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn
@@ -1,9 +1,9 @@
 import("//clang/lib/ARCMigrate/enable.gni")
+import("//llvm/utils/gn/build/symbol_exports.gni")
 import("//llvm/version.gni")
 
 # This build file is just enough to get check-clang to pass, it's missing
 # several things from the CMake build:
-# - using libclang.exports
 # - a build target copying the Python bindings
 # - the GN linux build always builds without -fPIC (as if LLVM_ENABLE_PIC=OFF
 #   in the CMake build), so libclang is always a static library on linux
@@ -16,6 +16,10 @@ if (host_os != "win" && host_os != "mac") {
   libclang_target_type = "static_library"
 }
 
+symbol_exports("exports") {
+  exports_file = "libclang.exports"
+}
+
 target(libclang_target_type, "libclang") {
   configs += [ "//llvm/utils/gn/build:clang_code" ]
   deps = [
@@ -37,6 +41,10 @@ target(libclang_target_type, "libclang") {
     deps += [ "//clang/lib/ARCMigrate" ]
   }
 
+  if (libclang_target_type == "shared_library") {
+    deps += [ ":exports" ]
+  }
+
   defines = []
 
   if (host_os == "win") {
@@ -87,6 +95,4 @@ target(libclang_target_type, "libclang") {
       "-Wl,-rpath, at loader_path/../lib",
     ]
   }
-
-  # FIXME: Use libclang.exports
 }

diff  --git a/llvm/utils/gn/secondary/llvm/lib/Transforms/Hello/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Transforms/Hello/BUILD.gn
index 5ed1019c0933f..a55d956ac3b62 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Transforms/Hello/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Transforms/Hello/BUILD.gn
@@ -1,8 +1,16 @@
+import("//llvm/utils/gn/build/symbol_exports.gni")
+
 assert(host_os != "win", "loadable modules not supported on win")
 
+symbol_exports("exports") {
+  exports_file = "Hello.exports"
+}
+
 loadable_module("Hello") {
   output_name = "LLVMHello"
   deps = [
+    ":exports",
+
     # LLVMHello doesn't want to link in any LLVM code, it just
     # needs its headers.
     "//llvm/include/llvm/IR:public_tablegen",
@@ -15,6 +23,4 @@ loadable_module("Hello") {
     # for loadable_modules for now.
     cflags = [ "-fPIC" ]
   }
-
-  # FIXME: Use Hello.exports to remove all exports.
 }

diff  --git a/llvm/utils/gn/secondary/llvm/tools/bugpoint-passes/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/bugpoint-passes/BUILD.gn
index f2ead028677a5..1f7580bbbac64 100644
--- a/llvm/utils/gn/secondary/llvm/tools/bugpoint-passes/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/tools/bugpoint-passes/BUILD.gn
@@ -1,8 +1,16 @@
+import("//llvm/utils/gn/build/symbol_exports.gni")
+
 assert(host_os != "win", "loadable modules not supported on win")
 
+symbol_exports("exports") {
+  exports_file = "bugpoint.exports"
+}
+
 loadable_module("bugpoint-passes") {
   output_name = "BugpointPasses"
   deps = [
+    ":exports",
+
     # BugpointPasses doesn't want to link in any LLVM code, it just
     # needs its headers.
     "//llvm/include/llvm/IR:public_tablegen",
@@ -15,6 +23,4 @@ loadable_module("bugpoint-passes") {
     # for loadable_modules for now.
     cflags = [ "-fPIC" ]
   }
-
-  # FIXME: Use bugpoint.exports to remove all exports.
 }

diff  --git a/llvm/utils/gn/secondary/llvm/tools/lto/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/lto/BUILD.gn
index 135b952c15352..418bdeb4fc068 100644
--- a/llvm/utils/gn/secondary/llvm/tools/lto/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/tools/lto/BUILD.gn
@@ -1,3 +1,4 @@
+import("//llvm/utils/gn/build/symbol_exports.gni")
 import("//llvm/version.gni")
 
 lto_target_type = "shared_library"
@@ -7,6 +8,10 @@ if (host_os != "mac" && host_os != "win") {
   lto_target_type = "static_library"
 }
 
+symbol_exports("exports") {
+  exports_file = "lto.exports"
+}
+
 target(lto_target_type, "lto") {
   output_name = "LTO"
   deps = [
@@ -24,6 +29,10 @@ target(lto_target_type, "lto") {
     "lto.cpp",
   ]
 
+  if (lto_target_type == "shared_library") {
+    deps += [ ":exports" ]
+  }
+
   if (host_os == "mac") {
     ldflags = [
       "-Wl,-compatibility_version,1",
@@ -34,6 +43,4 @@ target(lto_target_type, "lto") {
       "-Wl,-rpath, at loader_path/../lib",
     ]
   }
-
-  # FIXME: Use lto.exports
 }


        


More information about the llvm-commits mailing list