Skip to content

Commit

Permalink
[gn build] Use .export files
Browse files Browse the repository at this point in the history
Just fixing an old TODO, no dramatic behavior change.

Differential Revision: https://reviews.llvm.org/D102843
  • Loading branch information
nico committed May 20, 2021
1 parent f21f1ee commit fc96961
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 9 deletions.
59 changes: 59 additions & 0 deletions 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" ]
}
}
43 changes: 43 additions & 0 deletions 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())
12 changes: 9 additions & 3 deletions 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
Expand All @@ -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 = [
Expand All @@ -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") {
Expand Down Expand Up @@ -87,6 +95,4 @@ target(libclang_target_type, "libclang") {
"-Wl,-rpath,@loader_path/../lib",
]
}

# FIXME: Use libclang.exports
}
10 changes: 8 additions & 2 deletions 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",
Expand All @@ -15,6 +23,4 @@ loadable_module("Hello") {
# for loadable_modules for now.
cflags = [ "-fPIC" ]
}

# FIXME: Use Hello.exports to remove all exports.
}
10 changes: 8 additions & 2 deletions 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",
Expand All @@ -15,6 +23,4 @@ loadable_module("bugpoint-passes") {
# for loadable_modules for now.
cflags = [ "-fPIC" ]
}

# FIXME: Use bugpoint.exports to remove all exports.
}
11 changes: 9 additions & 2 deletions 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"
Expand All @@ -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 = [
Expand All @@ -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",
Expand All @@ -34,6 +43,4 @@ target(lto_target_type, "lto") {
"-Wl,-rpath,@loader_path/../lib",
]
}

# FIXME: Use lto.exports
}

0 comments on commit fc96961

Please sign in to comment.