llvm.org GIT mirror llvm / 10add60
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246527 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Wilkins 4 years ago
5 changed file(s) with 133 addition(s) and 59 deletion(s). Raw diff Collapse all Expand all
346346 option (LLVM_BUILD_EXTERNAL_COMPILER_RT
347347 "Build compiler-rt as an external project." OFF)
348348
349 option(LLVM_BUILD_LLVM_DYLIB "Build libllvm dynamic library" OFF)
350 option(LLVM_DYLIB_EXPORT_ALL "Export all symbols from libLLVM.dylib (default is C API only" OFF)
351 option(LLVM_DISABLE_LLVM_DYLIB_ATEXIT "Disable llvm-shlib's atexit destructors." ON)
349 option(LLVM_LINK_LLVM_DYLIB "Link tools against the libllvm dynamic library" OFF)
350 option(LLVM_BUILD_LLVM_DYLIB "Build libllvm dynamic library" ${LLVM_LINK_LLVM_DYLIB})
351 option(LLVM_DYLIB_EXPORT_ALL "Export all symbols from libLLVM.dylib (default is C API only" ${LLVM_LINK_LLVM_DYLIB})
352 set(LLVM_DISABLE_LLVM_DYLIB_ATEXIT_DEFAULT ON)
353 if (LLVM_LINK_LLVM_DYLIB)
354 set(LLVM_DISABLE_LLVM_DYLIB_ATEXIT_DEFAULT OFF)
355 endif()
356 option(LLVM_DISABLE_LLVM_DYLIB_ATEXIT "Disable llvm-shlib's atexit destructors." ${LLVM_DISABLE_LLVM_DYLIB_ATEXIT_DEFAULT})
352357 if(LLVM_DISABLE_LLVM_DYLIB_ATEXIT)
353358 set(DISABLE_LLVM_DYLIB_ATEXIT 1)
354359 endif()
4040 # Assume that;
4141 # - LLVM_COMPILE_FLAGS is list.
4242 # - PROPERTY COMPILE_FLAGS is string.
43 string(REPLACE ";" " " target_compile_flags "${LLVM_COMPILE_FLAGS}")
43 string(REPLACE ";" " " target_compile_flags " ${LLVM_COMPILE_FLAGS}")
4444
4545 if(update_src_props)
4646 foreach(fn ${sources})
302302 # MODULE
303303 # Target ${name} might not be created on unsupported platforms.
304304 # Check with "if(TARGET ${name})".
305 # DISABLE_LLVM_LINK_LLVM_DYLIB
306 # Do not link this library to libLLVM, even if
307 # LLVM_LINK_LLVM_DYLIB is enabled.
305308 # OUTPUT_NAME name
306309 # Corresponds to OUTPUT_NAME in target properties.
307310 # DEPENDS targets...
315318 # )
316319 function(llvm_add_library name)
317320 cmake_parse_arguments(ARG
318 "MODULE;SHARED;STATIC"
321 "MODULE;SHARED;STATIC;DISABLE_LLVM_LINK_LLVM_DYLIB"
319322 "OUTPUT_NAME"
320323 "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
321324 ${ARGN})
443446 # property has been set to an empty value.
444447 get_property(lib_deps GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_${name})
445448
446 llvm_map_components_to_libnames(llvm_libs
447 ${ARG_LINK_COMPONENTS}
448 ${LLVM_LINK_COMPONENTS}
449 )
449 if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_STATIC AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
450 set(llvm_libs LLVM)
451 else()
452 llvm_map_components_to_libnames(llvm_libs
453 ${ARG_LINK_COMPONENTS}
454 ${LLVM_LINK_COMPONENTS}
455 )
456 endif()
450457
451458 if(CMAKE_VERSION VERSION_LESS 2.8.12)
452459 # Link libs w/o keywords, assuming PUBLIC.
561568
562569
563570 macro(add_llvm_executable name)
564 llvm_process_sources( ALL_FILES ${ARGN} )
571 cmake_parse_arguments(ARG "DISABLE_LLVM_LINK_LLVM_DYLIB" "" "" ${ARGN})
572 llvm_process_sources( ALL_FILES ${ARG_UNPARSED_ARGUMENTS} )
565573
566574 # Generate objlib
567575 if(LLVM_ENABLE_OBJLIB)
603611
604612 set(EXCLUDE_FROM_ALL OFF)
605613 set_output_directory(${name} ${LLVM_RUNTIME_OUTPUT_INTDIR} ${LLVM_LIBRARY_OUTPUT_INTDIR})
606 llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
614 if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
615 target_link_libraries(${name} LLVM)
616 else()
617 llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
618 endif()
607619 if( LLVM_COMMON_DEPENDS )
608620 add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
609621 endif( LLVM_COMMON_DEPENDS )
835847 set(cppflags "${cppflags} -I${d}")
836848 endforeach(d)
837849 set(ldflags "${CMAKE_EXE_LINKER_FLAGS}")
850 if (LLVM_LINK_LLVM_DYLIB)
851 set(linkmode "dylib")
852 else()
853 set(linkmode "component-libs")
854 endif()
838855 add_custom_command(OUTPUT ${binpath}
839 COMMAND ${CMAKE_BINARY_DIR}/bin/llvm-go "go=${GO_EXECUTABLE}" "cc=${cc}" "cxx=${cxx}" "cppflags=${cppflags}" "ldflags=${ldflags}"
856 COMMAND ${CMAKE_BINARY_DIR}/bin/llvm-go "go=${GO_EXECUTABLE}" "cc=${cc}" "cxx=${cxx}" "cppflags=${cppflags}" "ldflags=${ldflags}" "linkmode=${linkmode}"
840857 ${ARG_GOFLAGS} build -o ${binpath} ${pkgpath}
841858 DEPENDS llvm-config ${CMAKE_BINARY_DIR}/bin/llvm-go${CMAKE_EXECUTABLE_SUFFIX}
842859 ${llvmlibs} ${ARG_DEPENDS}
7676 # FIXME: It leaks to user, callee of add_tablegen.
7777 set(LLVM_ENABLE_OBJLIB ON)
7878
79 add_llvm_utility(${target} ${ARGN})
79 add_llvm_utility(
80 ${target} ${ARGN}
81 # libLLVM does not include the TableGen
82 # components, so we cannot link any tblgen
83 # utilities against it.
84 DISABLE_LLVM_LINK_LLVM_DYLIB)
85
8086 set(LLVM_LINK_COMPONENTS ${${target}_OLD_LLVM_LINK_COMPONENTS})
8187
8288 set(${project}_TABLEGEN "${target}" CACHE
2121 "path/filepath"
2222 "runtime"
2323 "strings"
24 )
25
26 const (
27 linkmodeComponentLibs = "component-libs"
28 linkmodeDylib = "dylib"
2429 )
2530
2631 type pkg struct {
6570 func llvmConfig(args ...string) string {
6671 configpath := os.Getenv("LLVM_CONFIG")
6772 if configpath == "" {
68 // strip llvm-go, add llvm-config
69 configpath = os.Args[0][:len(os.Args[0])-7] + "llvm-config"
73 bin, _ := filepath.Split(os.Args[0])
74 configpath = filepath.Join(bin, "llvm-config")
7075 }
7176
7277 cmd := exec.Command(configpath, args...)
78 cmd.Stderr = os.Stderr
7379 out, err := cmd.Output()
7480 if err != nil {
7581 panic(err.Error())
7783
7884 outstr := string(out)
7985 outstr = strings.TrimSuffix(outstr, "\n")
80 return strings.Replace(outstr, "\n", " ", -1)
81 }
82
83 func llvmFlags() compilerFlags {
84 ldflags := llvmConfig(append([]string{"--ldflags", "--libs", "--system-libs"}, components...)...)
86 outstr = strings.Replace(outstr, "\n", " ", -1)
87 return outstr
88 }
89
90 func llvmFlags(linkmode string) compilerFlags {
91 ldflags := llvmConfig("--ldflags")
92 switch linkmode {
93 case linkmodeComponentLibs:
94 ldflags += " " + llvmConfig(append([]string{"--libs"}, components...)...)
95 case linkmodeDylib:
96 ldflags += " -lLLVM"
97 default:
98 panic("invalid linkmode: " + linkmode)
99 }
100 ldflags += " " + llvmConfig("--system-libs")
85101 if runtime.GOOS != "darwin" {
86102 // OS X doesn't like -rpath with cgo. See:
87103 // https://code.google.com/p/go/issues/detail?id=7293
116132 fmt.Println(strings.Join(components, " "))
117133 }
118134
119 func printConfig() {
120 flags := llvmFlags()
135 func printConfig(linkmode string) {
136 flags := llvmFlags(linkmode)
121137
122138 fmt.Printf(`// +build !byollvm
123139
136152 `, flags.cpp, flags.cxx, flags.ld)
137153 }
138154
139 func runGoWithLLVMEnv(args []string, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags string) {
155 func runGoWithLLVMEnv(args []string, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags, linkmode string) {
140156 args = addTag(args, "byollvm")
141157
142158 srcdir := llvmConfig("--src-root")
165181 newgopathlist = append(newgopathlist, filepath.SplitList(os.Getenv("GOPATH"))...)
166182 newgopath := strings.Join(newgopathlist, string(filepath.ListSeparator))
167183
168 flags := llvmFlags()
184 flags := llvmFlags(linkmode)
169185
170186 newenv := []string{
171187 "CC=" + cc,
177193 "PATH=" + newpath,
178194 }
179195 if llgo != "" {
180 newenv = append(newenv, "GCCGO=" + llgo)
196 newenv = append(newenv, "GCCGO="+llgo)
181197 }
182198
183199 for _, v := range os.Environ() {
233249 ldflags := os.Getenv("CGO_LDFLAGS")
234250 gocmd := "go"
235251 llgo := ""
252 linkmode := linkmodeComponentLibs
253
254 flags := []struct {
255 name string
256 dest *string
257 }{
258 {"cc", &cc},
259 {"cxx", &cxx},
260 {"go", &gocmd},
261 {"llgo", &llgo},
262 {"cppflags", &cppflags},
263 {"ldflags", &ldflags},
264 {"linkmode", &linkmode},
265 }
236266
237267 args := os.Args[1:]
238 DONE: for {
239 switch {
240 case len(args) == 0:
268 LOOP:
269 for {
270 if len(args) == 0 {
241271 usage()
242 case strings.HasPrefix(args[0], "cc="):
243 cc = args[0][3:]
244 args = args[1:]
245 case strings.HasPrefix(args[0], "cxx="):
246 cxx = args[0][4:]
247 args = args[1:]
248 case strings.HasPrefix(args[0], "go="):
249 gocmd = args[0][3:]
250 args = args[1:]
251 case strings.HasPrefix(args[0], "llgo="):
252 llgo = args[0][5:]
253 args = args[1:]
254 case strings.HasPrefix(args[0], "cppflags="):
255 cppflags = args[0][9:]
256 args = args[1:]
257 case strings.HasPrefix(args[0], "cxxflags="):
258 cxxflags = args[0][9:]
259 args = args[1:]
260 case strings.HasPrefix(args[0], "ldflags="):
261 ldflags = args[0][8:]
262 args = args[1:]
263 default:
264 break DONE
265 }
272 }
273 for _, flag := range flags {
274 if strings.HasPrefix(args[0], flag.name+"=") {
275 *flag.dest = args[0][len(flag.name)+1:]
276 args = args[1:]
277 continue LOOP
278 }
279 }
280 break
266281 }
267282
268283 switch args[0] {
269284 case "build", "get", "install", "run", "test":
270 runGoWithLLVMEnv(args, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags)
285 runGoWithLLVMEnv(args, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags, linkmode)
271286 case "print-components":
272287 printComponents()
273288 case "print-config":
274 printConfig()
289 printConfig(linkmode)
275290 default:
276291 usage()
277292 }
11 # library is enabled by setting LLVM_BUILD_LLVM_DYLIB=yes on the CMake
22 # commandline. By default the shared library only exports the LLVM C API.
33
4 if(LLVM_LINK_LLVM_DYLIB)
5 if(DEFINED LLVM_DYLIB_COMPONENTS)
6 # To avoid inscrutable link errors, just disallow setting
7 # LLVM_DYLIB_COMPONENTS when we're intending to link tools
8 # and shared libraries with the dylib.
9 message(FATAL_ERROR "LLVM_DYLIB_COMPONENTS must not be set when LLVM_LINK_LLVM_DYLIB is ON")
10 endif()
11 if(NOT LLVM_DYLIB_EXPORT_ALL)
12 message(FATAL_ERROR "LLVM_DYLIB_EXPORT_ALL must be ON when LLVM_LINK_LLVM_DYLIB is ON")
13 endif()
14 set(LLVM_DYLIB_COMPONENTS all)
15 endif()
416
5 # You can configure which libraries from LLVM you want to include in the shared
6 # library by setting LLVM_DYLIB_COMPONENTS to a semi-colon delimited list of
7 # LLVM components. All compoenent names handled by llvm-config are valid.
8
17 # If LLVM_LINK_LLVM_DYLIB is not OFF, you can configure which libraries from
18 # LLVM you want to include in the shared library by setting
19 # LLVM_DYLIB_COMPONENTS to a semi-colon delimited list of LLVM components.
20 # All component names handled by llvm-config are valid.
921 if(NOT DEFINED LLVM_DYLIB_COMPONENTS)
1022 set(LLVM_DYLIB_COMPONENTS
1123 ${LLVM_TARGETS_TO_BUILD}
4355 )
4456
4557 llvm_map_components_to_libnames(LIB_NAMES ${LLVM_DYLIB_COMPONENTS})
58
59 if(LLVM_LINK_LLVM_DYLIB)
60 # libLLVM.so should not have any dependencies on any other LLVM
61 # shared libraries. When using the "all" pseudo-component,
62 # LLVM_AVAILABLE_LIBS is added to the dependencies, which may
63 # contain shared libraries (e.g. libLTO).
64 #
65 # Also exclude libLLVMTableGen for the following reasons:
66 # - it is only used by internal *-tblgen utilities;
67 # - it pollutes the global options space.
68 foreach(lib ${LIB_NAMES})
69 get_target_property(t ${lib} TYPE)
70 if("${lib}" STREQUAL "LLVMTableGen")
71 elseif("x${t}" STREQUAL "xSTATIC_LIBRARY")
72 list(APPEND FILTERED_LIB_NAMES ${lib})
73 endif()
74 endforeach()
75 set(LIB_NAMES ${FILTERED_LIB_NAMES})
76 endif()
4677
4778 if(NOT DEFINED LLVM_DYLIB_EXPORTED_SYMBOL_FILE)
4879
93124 add_custom_target(libLLVMExports DEPENDS ${LLVM_EXPORTED_SYMBOL_FILE})
94125 endif()
95126
96 add_llvm_library(LLVM SHARED ${SOURCES})
127 add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB ${SOURCES})
97128
98129 list(REMOVE_DUPLICATES LIB_NAMES)
99130 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") # FIXME: It should be "GNU ld for elf"