mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
Enable linking tools, shared libraries against libLLVM
Summary: Three closely related changes, to have a mode in which we link all executables and shared libraries against libLLVM. 1. Add a new LLVM_LINK_LLVM_DYLIB cmake option, which, when ON, will link executables and shared libraries against libLLVM. For this to work, it is necessary to also set LLVM_BUILD_LLVM_DYLIB and LLVM_DYLIB_EXPORT_ALL. It is not strictly necessary to set LLVM_DISABLE_LLVM_DYLIB_ATEXIT, but we also default to OFF in this mode, or tools tend to misbehave (e.g. stdout may not flush on exit when output is buffered.) llvm-config and Tablegen do not use libLLVM, as they are dependencies of libLLVM. 2. Modify llvm-go to take a new flag, "linkmode=component-libs|dylib". Depending on which one is passed (default is component-libs), we link with the individual libraries or libLLVM respectively. We pass in dylib when LLVM_LINK_LLVM_DYLIB is ON. 3. Fix LLVM_DYLIB_EXPORT_ALL on Linux, and expand the symbols exported to actually export all. Don't strip leading underscore from symbols on Linux, and make sure we get all exported symbols and weak-with-default symbols ("W" in nm output). Without these changes, passes won't load because the "Annotate..." symbols defined in lib/Support/Valigrind.cpp are not found. Testing: - Ran default build ("ninja") with LLVM, clang, compiler-rt, llgo, lldb. - Ran "check", "check-clang", "check-tsan", "check-libgo" targets. I've never had much success with LLDB tests, and llgoi is currently broken so check-llgo fails for an unrelated reason. - Ran "lldb" to ensure it loads. Reviewers: chandlerc, beanz, pcc, rnk Subscribers: rnk, chapuni, sylvestre.ledru, llvm-commits Differential Revision: http://reviews.llvm.org/D12488 llvm-svn: 246527
This commit is contained in:
parent
bcaa9eed06
commit
55390f2377
@ -347,9 +347,14 @@ option (LLVM_ENABLE_SPHINX "Use Sphinx to generate llvm documentation." OFF)
|
||||
option (LLVM_BUILD_EXTERNAL_COMPILER_RT
|
||||
"Build compiler-rt as an external project." OFF)
|
||||
|
||||
option(LLVM_BUILD_LLVM_DYLIB "Build libllvm dynamic library" OFF)
|
||||
option(LLVM_DYLIB_EXPORT_ALL "Export all symbols from libLLVM.dylib (default is C API only" OFF)
|
||||
option(LLVM_DISABLE_LLVM_DYLIB_ATEXIT "Disable llvm-shlib's atexit destructors." ON)
|
||||
option(LLVM_LINK_LLVM_DYLIB "Link tools against the libllvm dynamic library" OFF)
|
||||
option(LLVM_BUILD_LLVM_DYLIB "Build libllvm dynamic library" ${LLVM_LINK_LLVM_DYLIB})
|
||||
option(LLVM_DYLIB_EXPORT_ALL "Export all symbols from libLLVM.dylib (default is C API only" ${LLVM_LINK_LLVM_DYLIB})
|
||||
set(LLVM_DISABLE_LLVM_DYLIB_ATEXIT_DEFAULT ON)
|
||||
if (LLVM_LINK_LLVM_DYLIB)
|
||||
set(LLVM_DISABLE_LLVM_DYLIB_ATEXIT_DEFAULT OFF)
|
||||
endif()
|
||||
option(LLVM_DISABLE_LLVM_DYLIB_ATEXIT "Disable llvm-shlib's atexit destructors." ${LLVM_DISABLE_LLVM_DYLIB_ATEXIT_DEFAULT})
|
||||
if(LLVM_DISABLE_LLVM_DYLIB_ATEXIT)
|
||||
set(DISABLE_LLVM_DYLIB_ATEXIT 1)
|
||||
endif()
|
||||
|
@ -303,6 +303,9 @@ endfunction(set_windows_version_resource_properties)
|
||||
# MODULE
|
||||
# Target ${name} might not be created on unsupported platforms.
|
||||
# Check with "if(TARGET ${name})".
|
||||
# DISABLE_LLVM_LINK_LLVM_DYLIB
|
||||
# Do not link this library to libLLVM, even if
|
||||
# LLVM_LINK_LLVM_DYLIB is enabled.
|
||||
# OUTPUT_NAME name
|
||||
# Corresponds to OUTPUT_NAME in target properties.
|
||||
# DEPENDS targets...
|
||||
@ -316,7 +319,7 @@ endfunction(set_windows_version_resource_properties)
|
||||
# )
|
||||
function(llvm_add_library name)
|
||||
cmake_parse_arguments(ARG
|
||||
"MODULE;SHARED;STATIC"
|
||||
"MODULE;SHARED;STATIC;DISABLE_LLVM_LINK_LLVM_DYLIB"
|
||||
"OUTPUT_NAME"
|
||||
"ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
|
||||
${ARGN})
|
||||
@ -444,10 +447,14 @@ function(llvm_add_library name)
|
||||
# property has been set to an empty value.
|
||||
get_property(lib_deps GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_${name})
|
||||
|
||||
if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_STATIC AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
|
||||
set(llvm_libs LLVM)
|
||||
else()
|
||||
llvm_map_components_to_libnames(llvm_libs
|
||||
${ARG_LINK_COMPONENTS}
|
||||
${LLVM_LINK_COMPONENTS}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
# Link libs w/o keywords, assuming PUBLIC.
|
||||
@ -562,7 +569,8 @@ endmacro(add_llvm_loadable_module name)
|
||||
|
||||
|
||||
macro(add_llvm_executable name)
|
||||
llvm_process_sources( ALL_FILES ${ARGN} )
|
||||
cmake_parse_arguments(ARG "DISABLE_LLVM_LINK_LLVM_DYLIB" "" "" ${ARGN})
|
||||
llvm_process_sources( ALL_FILES ${ARG_UNPARSED_ARGUMENTS} )
|
||||
|
||||
# Generate objlib
|
||||
if(LLVM_ENABLE_OBJLIB)
|
||||
@ -604,7 +612,11 @@ macro(add_llvm_executable name)
|
||||
|
||||
set(EXCLUDE_FROM_ALL OFF)
|
||||
set_output_directory(${name} ${LLVM_RUNTIME_OUTPUT_INTDIR} ${LLVM_LIBRARY_OUTPUT_INTDIR})
|
||||
if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
|
||||
target_link_libraries(${name} LLVM)
|
||||
else()
|
||||
llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
|
||||
endif()
|
||||
if( LLVM_COMMON_DEPENDS )
|
||||
add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
|
||||
endif( LLVM_COMMON_DEPENDS )
|
||||
@ -836,8 +848,13 @@ function(llvm_add_go_executable binary pkgpath)
|
||||
set(cppflags "${cppflags} -I${d}")
|
||||
endforeach(d)
|
||||
set(ldflags "${CMAKE_EXE_LINKER_FLAGS}")
|
||||
if (LLVM_LINK_LLVM_DYLIB)
|
||||
set(linkmode "dylib")
|
||||
else()
|
||||
set(linkmode "component-libs")
|
||||
endif()
|
||||
add_custom_command(OUTPUT ${binpath}
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/llvm-go "go=${GO_EXECUTABLE}" "cc=${cc}" "cxx=${cxx}" "cppflags=${cppflags}" "ldflags=${ldflags}"
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/llvm-go "go=${GO_EXECUTABLE}" "cc=${cc}" "cxx=${cxx}" "cppflags=${cppflags}" "ldflags=${ldflags}" "linkmode=${linkmode}"
|
||||
${ARG_GOFLAGS} build -o ${binpath} ${pkgpath}
|
||||
DEPENDS llvm-config ${CMAKE_BINARY_DIR}/bin/llvm-go${CMAKE_EXECUTABLE_SUFFIX}
|
||||
${llvmlibs} ${ARG_DEPENDS}
|
||||
|
@ -77,7 +77,13 @@ macro(add_tablegen target project)
|
||||
# FIXME: It leaks to user, callee of add_tablegen.
|
||||
set(LLVM_ENABLE_OBJLIB ON)
|
||||
|
||||
add_llvm_utility(${target} ${ARGN})
|
||||
add_llvm_utility(
|
||||
${target} ${ARGN}
|
||||
# libLLVM does not include the TableGen
|
||||
# components, so we cannot link any tblgen
|
||||
# utilities against it.
|
||||
DISABLE_LLVM_LINK_LLVM_DYLIB)
|
||||
|
||||
set(LLVM_LINK_COMPONENTS ${${target}_OLD_LLVM_LINK_COMPONENTS})
|
||||
|
||||
set(${project}_TABLEGEN "${target}" CACHE
|
||||
|
@ -24,6 +24,11 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
linkmodeComponentLibs = "component-libs"
|
||||
linkmodeDylib = "dylib"
|
||||
)
|
||||
|
||||
type pkg struct {
|
||||
llvmpath, pkgpath string
|
||||
}
|
||||
@ -66,11 +71,12 @@ var components = []string{
|
||||
func llvmConfig(args ...string) string {
|
||||
configpath := os.Getenv("LLVM_CONFIG")
|
||||
if configpath == "" {
|
||||
// strip llvm-go, add llvm-config
|
||||
configpath = os.Args[0][:len(os.Args[0])-7] + "llvm-config"
|
||||
bin, _ := filepath.Split(os.Args[0])
|
||||
configpath = filepath.Join(bin, "llvm-config")
|
||||
}
|
||||
|
||||
cmd := exec.Command(configpath, args...)
|
||||
cmd.Stderr = os.Stderr
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
@ -78,11 +84,21 @@ func llvmConfig(args ...string) string {
|
||||
|
||||
outstr := string(out)
|
||||
outstr = strings.TrimSuffix(outstr, "\n")
|
||||
return strings.Replace(outstr, "\n", " ", -1)
|
||||
outstr = strings.Replace(outstr, "\n", " ", -1)
|
||||
return outstr
|
||||
}
|
||||
|
||||
func llvmFlags() compilerFlags {
|
||||
ldflags := llvmConfig(append([]string{"--ldflags", "--libs", "--system-libs"}, components...)...)
|
||||
func llvmFlags(linkmode string) compilerFlags {
|
||||
ldflags := llvmConfig("--ldflags")
|
||||
switch linkmode {
|
||||
case linkmodeComponentLibs:
|
||||
ldflags += " " + llvmConfig(append([]string{"--libs"}, components...)...)
|
||||
case linkmodeDylib:
|
||||
ldflags += " -lLLVM"
|
||||
default:
|
||||
panic("invalid linkmode: " + linkmode)
|
||||
}
|
||||
ldflags += " " + llvmConfig("--system-libs")
|
||||
if runtime.GOOS != "darwin" {
|
||||
// OS X doesn't like -rpath with cgo. See:
|
||||
// https://code.google.com/p/go/issues/detail?id=7293
|
||||
@ -117,8 +133,8 @@ func printComponents() {
|
||||
fmt.Println(strings.Join(components, " "))
|
||||
}
|
||||
|
||||
func printConfig() {
|
||||
flags := llvmFlags()
|
||||
func printConfig(linkmode string) {
|
||||
flags := llvmFlags(linkmode)
|
||||
|
||||
fmt.Printf(`// +build !byollvm
|
||||
|
||||
@ -137,7 +153,7 @@ type (run_build_sh int)
|
||||
`, flags.cpp, flags.cxx, flags.ld)
|
||||
}
|
||||
|
||||
func runGoWithLLVMEnv(args []string, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags string) {
|
||||
func runGoWithLLVMEnv(args []string, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags, linkmode string) {
|
||||
args = addTag(args, "byollvm")
|
||||
|
||||
srcdir := llvmConfig("--src-root")
|
||||
@ -166,7 +182,7 @@ func runGoWithLLVMEnv(args []string, cc, cxx, gocmd, llgo, cppflags, cxxflags, l
|
||||
newgopathlist = append(newgopathlist, filepath.SplitList(os.Getenv("GOPATH"))...)
|
||||
newgopath := strings.Join(newgopathlist, string(filepath.ListSeparator))
|
||||
|
||||
flags := llvmFlags()
|
||||
flags := llvmFlags(linkmode)
|
||||
|
||||
newenv := []string{
|
||||
"CC=" + cc,
|
||||
@ -234,45 +250,44 @@ func main() {
|
||||
ldflags := os.Getenv("CGO_LDFLAGS")
|
||||
gocmd := "go"
|
||||
llgo := ""
|
||||
linkmode := linkmodeComponentLibs
|
||||
|
||||
flags := []struct {
|
||||
name string
|
||||
dest *string
|
||||
}{
|
||||
{"cc", &cc},
|
||||
{"cxx", &cxx},
|
||||
{"go", &gocmd},
|
||||
{"llgo", &llgo},
|
||||
{"cppflags", &cppflags},
|
||||
{"ldflags", &ldflags},
|
||||
{"linkmode", &linkmode},
|
||||
}
|
||||
|
||||
args := os.Args[1:]
|
||||
DONE: for {
|
||||
switch {
|
||||
case len(args) == 0:
|
||||
LOOP:
|
||||
for {
|
||||
if len(args) == 0 {
|
||||
usage()
|
||||
case strings.HasPrefix(args[0], "cc="):
|
||||
cc = args[0][3:]
|
||||
args = args[1:]
|
||||
case strings.HasPrefix(args[0], "cxx="):
|
||||
cxx = args[0][4:]
|
||||
args = args[1:]
|
||||
case strings.HasPrefix(args[0], "go="):
|
||||
gocmd = args[0][3:]
|
||||
args = args[1:]
|
||||
case strings.HasPrefix(args[0], "llgo="):
|
||||
llgo = args[0][5:]
|
||||
args = args[1:]
|
||||
case strings.HasPrefix(args[0], "cppflags="):
|
||||
cppflags = args[0][9:]
|
||||
args = args[1:]
|
||||
case strings.HasPrefix(args[0], "cxxflags="):
|
||||
cxxflags = args[0][9:]
|
||||
args = args[1:]
|
||||
case strings.HasPrefix(args[0], "ldflags="):
|
||||
ldflags = args[0][8:]
|
||||
args = args[1:]
|
||||
default:
|
||||
break DONE
|
||||
}
|
||||
for _, flag := range flags {
|
||||
if strings.HasPrefix(args[0], flag.name+"=") {
|
||||
*flag.dest = args[0][len(flag.name)+1:]
|
||||
args = args[1:]
|
||||
continue LOOP
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
switch args[0] {
|
||||
case "build", "get", "install", "run", "test":
|
||||
runGoWithLLVMEnv(args, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags)
|
||||
runGoWithLLVMEnv(args, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags, linkmode)
|
||||
case "print-components":
|
||||
printComponents()
|
||||
case "print-config":
|
||||
printConfig()
|
||||
printConfig(linkmode)
|
||||
default:
|
||||
usage()
|
||||
}
|
||||
|
@ -2,11 +2,23 @@
|
||||
# library is enabled by setting LLVM_BUILD_LLVM_DYLIB=yes on the CMake
|
||||
# commandline. By default the shared library only exports the LLVM C API.
|
||||
|
||||
if(LLVM_LINK_LLVM_DYLIB)
|
||||
if(DEFINED LLVM_DYLIB_COMPONENTS)
|
||||
# To avoid inscrutable link errors, just disallow setting
|
||||
# LLVM_DYLIB_COMPONENTS when we're intending to link tools
|
||||
# and shared libraries with the dylib.
|
||||
message(FATAL_ERROR "LLVM_DYLIB_COMPONENTS must not be set when LLVM_LINK_LLVM_DYLIB is ON")
|
||||
endif()
|
||||
if(NOT LLVM_DYLIB_EXPORT_ALL)
|
||||
message(FATAL_ERROR "LLVM_DYLIB_EXPORT_ALL must be ON when LLVM_LINK_LLVM_DYLIB is ON")
|
||||
endif()
|
||||
set(LLVM_DYLIB_COMPONENTS all)
|
||||
endif()
|
||||
|
||||
# You can configure which libraries from LLVM you want to include in the shared
|
||||
# library by setting LLVM_DYLIB_COMPONENTS to a semi-colon delimited list of
|
||||
# LLVM components. All compoenent names handled by llvm-config are valid.
|
||||
|
||||
# If LLVM_LINK_LLVM_DYLIB is not OFF, you can configure which libraries from
|
||||
# LLVM you want to include in the shared library by setting
|
||||
# LLVM_DYLIB_COMPONENTS to a semi-colon delimited list of LLVM components.
|
||||
# All component names handled by llvm-config are valid.
|
||||
if(NOT DEFINED LLVM_DYLIB_COMPONENTS)
|
||||
set(LLVM_DYLIB_COMPONENTS
|
||||
${LLVM_TARGETS_TO_BUILD}
|
||||
@ -45,6 +57,25 @@ set(SOURCES
|
||||
|
||||
llvm_map_components_to_libnames(LIB_NAMES ${LLVM_DYLIB_COMPONENTS})
|
||||
|
||||
if(LLVM_LINK_LLVM_DYLIB)
|
||||
# libLLVM.so should not have any dependencies on any other LLVM
|
||||
# shared libraries. When using the "all" pseudo-component,
|
||||
# LLVM_AVAILABLE_LIBS is added to the dependencies, which may
|
||||
# contain shared libraries (e.g. libLTO).
|
||||
#
|
||||
# Also exclude libLLVMTableGen for the following reasons:
|
||||
# - it is only used by internal *-tblgen utilities;
|
||||
# - it pollutes the global options space.
|
||||
foreach(lib ${LIB_NAMES})
|
||||
get_target_property(t ${lib} TYPE)
|
||||
if("${lib}" STREQUAL "LLVMTableGen")
|
||||
elseif("x${t}" STREQUAL "xSTATIC_LIBRARY")
|
||||
list(APPEND FILTERED_LIB_NAMES ${lib})
|
||||
endif()
|
||||
endforeach()
|
||||
set(LIB_NAMES ${FILTERED_LIB_NAMES})
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED LLVM_DYLIB_EXPORTED_SYMBOL_FILE)
|
||||
|
||||
if( WIN32 AND NOT CYGWIN )
|
||||
@ -94,7 +125,7 @@ else()
|
||||
add_custom_target(libLLVMExports DEPENDS ${LLVM_EXPORTED_SYMBOL_FILE})
|
||||
endif()
|
||||
|
||||
add_llvm_library(LLVM SHARED ${SOURCES})
|
||||
add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB ${SOURCES})
|
||||
|
||||
list(REMOVE_DUPLICATES LIB_NAMES)
|
||||
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") # FIXME: It should be "GNU ld for elf"
|
||||
|
Loading…
x
Reference in New Issue
Block a user