[libcxx] r220118 - [libcxx] Add support for building and testing with an ABI library not along linker paths

Eric Fiselier eric at efcs.ca
Fri Oct 17 18:15:17 PDT 2014


Author: ericwf
Date: Fri Oct 17 20:15:17 2014
New Revision: 220118

URL: http://llvm.org/viewvc/llvm-project?rev=220118&view=rev
Log:
[libcxx] Add support for building and testing with an ABI library not along linker paths

Summary:
This patch adds support for building/testing libc++ with an ABI library that the linker would not normally find.

- `CMAKE_LIBRARY_PATH` is used to specify the list of search directories.
- The ABI library is now found using `find_library` instead of assuming its along the linker's search path.
- `CMAKE_LIBRARY_PATH` is passed to our LIT config as `library_paths`.
- For each path in `library_paths` the following flags are added `-L<path> -Wl,-rpath -Wl,<path>`

Some changes in existing behavior were also added:
- `target_link_libraries` is now passed the ABI library file instead of the library name. Ex `target_link_libraries(cxx "/usr/lib/libc++abi.so")` vs `target_link_libraries(cxx "c++abi")`.
- `-Wl,-rpath -Wl,<path>` is now used on OSX to link to libc++ instead of env['DYLD_LIBRARY_PATH'] if `use_system_lib=False`.




Reviewers: mclow.lists, danalbert, EricWF

Reviewed By: EricWF

Subscribers: emaste, cfe-commits

Differential Revision: http://reviews.llvm.org/D5038

Added:
    libcxx/trunk/cmake/Modules/HandleLibCXXABI.cmake
Modified:
    libcxx/trunk/CMakeLists.txt
    libcxx/trunk/test/lit.cfg
    libcxx/trunk/test/lit.site.cfg.in
    libcxx/trunk/www/index.html

Modified: libcxx/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/CMakeLists.txt?rev=220118&r1=220117&r2=220118&view=diff
==============================================================================
--- libcxx/trunk/CMakeLists.txt (original)
+++ libcxx/trunk/CMakeLists.txt Fri Oct 17 20:15:17 2014
@@ -84,104 +84,11 @@ get_target_triple(LIBCXX_TARGET_TRIPLE
   )
 set(LIBCXX_TARGET_TRIPLE ${LIBCXX_TARGET_TRIPLE} CACHE STRING "Target triple.")
 
-#===============================================================================
-# Add an ABI library if appropriate
-#===============================================================================
-
-#
-# _setup_abi: Set up the build to use an ABI library
-#
-# Parameters:
-#   abidefines: A list of defines needed to compile libc++ with the ABI library
-#   abilibs   : A list of libraries to link against
-#   abifiles  : A list of files (which may be relative paths) to copy into the
-#               libc++ build tree for the build.  These files will also be
-#               installed alongside the libc++ headers.
-#   abidirs   : A list of relative paths to create under an include directory
-#               in the libc++ build directory.
-#
-macro(setup_abi_lib abipathvar abidefines abilibs abifiles abidirs)
-  list(APPEND LIBCXX_CXX_FEATURE_FLAGS ${abidefines})
-  set(${abipathvar} "${${abipathvar}}"
-    CACHE PATH
-    "Paths to C++ ABI header directories separated by ';'." FORCE
-    )
-  set(LIBCXX_CXX_ABI_LIBRARIES ${abilibs})
-  set(LIBCXX_ABILIB_FILES ${abifiles})
-
-  file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include")
-  foreach(_d ${abidirs})
-    file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include/${_d}")
-  endforeach()
-
-  foreach(fpath ${LIBCXX_ABILIB_FILES})
-    set(found FALSE)
-    foreach(incpath ${${abipathvar}})
-      if (EXISTS "${incpath}/${fpath}")
-        set(found TRUE)
-        get_filename_component(dstdir ${fpath} PATH)
-        get_filename_component(ifile ${fpath} NAME)
-        file(COPY "${incpath}/${fpath}"
-          DESTINATION "${CMAKE_BINARY_DIR}/include/${dstdir}"
-          )
-        install(FILES "${CMAKE_BINARY_DIR}/include/${fpath}"
-          DESTINATION include/c++/v1/${dstdir}
-          PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
-          )
-        list(APPEND abilib_headers "${CMAKE_BINARY_DIR}/include/${fpath}")
-      endif()
-    endforeach()
-    if (NOT found)
-      message(FATAL_ERROR "Failed to find ${fpath}")
-    endif()
-  endforeach()
-
-  add_custom_target(LIBCXX_CXX_ABI_DEPS DEPENDS ${abilib_headers})
-  include_directories("${CMAKE_BINARY_DIR}/include")
-
-endmacro()
-
-if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR
-    "${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libsupc++")
-  set(_LIBSUPCXX_INCLUDE_FILES
-    cxxabi.h bits/c++config.h bits/os_defines.h bits/cpu_defines.h
-    bits/cxxabi_tweaks.h bits/cxxabi_forced.h
-    )
-  if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++")
-    set(_LIBSUPCXX_DEFINES "-DLIBSTDCXX")
-    set(_LIBSUPCXX_LIBNAME stdc++)
-  else()
-    set(_LIBSUPCXX_DEFINES "")
-    set(_LIBSUPCXX_LIBNAME supc++)
-  endif()
-  setup_abi_lib("LIBCXX_LIBSUPCXX_INCLUDE_PATHS"
-    "-D__GLIBCXX__ ${_LIBSUPCXX_DEFINES}"
-    "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_INCLUDE_FILES}" "bits"
-    )
-elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi")
-  if (LIBCXX_CXX_ABI_INTREE)
-    # Link against just-built "cxxabi" target.
-    set(CXXABI_LIBNAME cxxabi)
-  else()
-    # Assume c++abi is installed in the system, rely on -lc++abi link flag.
-    set(CXXABI_LIBNAME "c++abi")
-  endif()
-  setup_abi_lib("LIBCXX_LIBCXXABI_INCLUDE_PATHS" ""
-    ${CXXABI_LIBNAME} "cxxabi.h" ""
-    )
-elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxrt")
-  setup_abi_lib("LIBCXX_LIBCXXRT_INCLUDE_PATHS" "-DLIBCXXRT"
-    "cxxrt" "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h" ""
-    )
-elseif (NOT "${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "none")
-  message(FATAL_ERROR
-    "Currently libstdc++, libsupc++, libcxxabi, libcxxrt and none are "
-    "supported for c++ abi."
-    )
-endif ()
 
 # Configure compiler.
 include(config-ix)
+# Configure ABI library
+include(HandleLibCXXABI)
 
 #===============================================================================
 # Setup Compiler Flags

Added: libcxx/trunk/cmake/Modules/HandleLibCXXABI.cmake
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/cmake/Modules/HandleLibCXXABI.cmake?rev=220118&view=auto
==============================================================================
--- libcxx/trunk/cmake/Modules/HandleLibCXXABI.cmake (added)
+++ libcxx/trunk/cmake/Modules/HandleLibCXXABI.cmake Fri Oct 17 20:15:17 2014
@@ -0,0 +1,111 @@
+
+#===============================================================================
+# Add an ABI library if appropriate
+#===============================================================================
+
+#
+# _setup_abi: Set up the build to use an ABI library
+#
+# Parameters:
+#   abidefines: A list of defines needed to compile libc++ with the ABI library
+#   abilibs   : A list of libraries to link against
+#   abifiles  : A list of files (which may be relative paths) to copy into the
+#               libc++ build tree for the build.  These files will also be
+#               installed alongside the libc++ headers.
+#   abidirs   : A list of relative paths to create under an include directory
+#               in the libc++ build directory.
+#
+macro(setup_abi_lib abipathvar abidefines abilibs abifiles abidirs)
+  list(APPEND LIBCXX_CXX_FEATURE_FLAGS ${abidefines})
+  set(${abipathvar} "${${abipathvar}}"
+    CACHE PATH
+    "Paths to C++ ABI header directories separated by ';'." FORCE
+    )
+
+  # To allow for libraries installed along non-default paths we use find_library
+  # to locate the ABI libraries we want. Making sure to clean the cache before
+  # each run of find_library.
+  set(LIBCXX_CXX_ABI_LIBRARIES "")
+  foreach(alib ${abilibs})
+    unset(_Res CACHE)
+    find_library(_Res ${alib})
+    if (${_Res} STREQUAL "_Res-NOTFOUND")
+      message(FATAL_ERROR "Failed to find ABI library: ${alib}")
+    else()
+      message(STATUS "Adding ABI library: ${_Res}")
+      list(APPEND LIBCXX_CXX_ABI_LIBRARIES ${_Res})
+    endif()
+  endforeach()
+
+  set(LIBCXX_ABILIB_FILES ${abifiles})
+
+  file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include")
+  foreach(_d ${abidirs})
+    file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include/${_d}")
+  endforeach()
+
+  foreach(fpath ${LIBCXX_ABILIB_FILES})
+    set(found FALSE)
+    foreach(incpath ${${abipathvar}})
+      if (EXISTS "${incpath}/${fpath}")
+        set(found TRUE)
+        get_filename_component(dstdir ${fpath} PATH)
+        get_filename_component(ifile ${fpath} NAME)
+        file(COPY "${incpath}/${fpath}"
+          DESTINATION "${CMAKE_BINARY_DIR}/include/${dstdir}"
+          )
+        install(FILES "${CMAKE_BINARY_DIR}/include/${fpath}"
+          DESTINATION include/c++/v1/${dstdir}
+          PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+          )
+        list(APPEND abilib_headers "${CMAKE_BINARY_DIR}/include/${fpath}")
+      endif()
+    endforeach()
+    if (NOT found)
+      message(FATAL_ERROR "Failed to find ${fpath}")
+    endif()
+  endforeach()
+
+  add_custom_target(LIBCXX_CXX_ABI_DEPS DEPENDS ${abilib_headers})
+  include_directories("${CMAKE_BINARY_DIR}/include")
+
+endmacro()
+
+if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR
+    "${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libsupc++")
+  set(_LIBSUPCXX_INCLUDE_FILES
+    cxxabi.h bits/c++config.h bits/os_defines.h bits/cpu_defines.h
+    bits/cxxabi_tweaks.h bits/cxxabi_forced.h
+    )
+  if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++")
+    set(_LIBSUPCXX_DEFINES "-DLIBSTDCXX")
+    set(_LIBSUPCXX_LIBNAME stdc++)
+  else()
+    set(_LIBSUPCXX_DEFINES "")
+    set(_LIBSUPCXX_LIBNAME supc++)
+  endif()
+  setup_abi_lib("LIBCXX_LIBSUPCXX_INCLUDE_PATHS"
+    "-D__GLIBCXX__ ${_LIBSUPCXX_DEFINES}"
+    "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_INCLUDE_FILES}" "bits"
+    )
+elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi")
+  if (LIBCXX_CXX_ABI_INTREE)
+    # Link against just-built "cxxabi" target.
+    set(CXXABI_LIBNAME cxxabi)
+  else()
+    # Assume c++abi is installed in the system, rely on -lc++abi link flag.
+    set(CXXABI_LIBNAME "c++abi")
+  endif()
+  setup_abi_lib("LIBCXX_LIBCXXABI_INCLUDE_PATHS" ""
+    ${CXXABI_LIBNAME} "cxxabi.h" ""
+    )
+elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxrt")
+  setup_abi_lib("LIBCXX_LIBCXXRT_INCLUDE_PATHS" "-DLIBCXXRT"
+    "cxxrt" "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h" ""
+    )
+elseif (NOT "${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "none")
+  message(FATAL_ERROR
+    "Currently libstdc++, libsupc++, libcxxabi, libcxxrt and none are "
+    "supported for c++ abi."
+    )
+endif ()
\ No newline at end of file

Modified: libcxx/trunk/test/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/lit.cfg?rev=220118&r1=220117&r2=220118&view=diff
==============================================================================
--- libcxx/trunk/test/lit.cfg (original)
+++ libcxx/trunk/test/lit.cfg Fri Oct 17 20:15:17 2014
@@ -197,6 +197,7 @@ class Configuration(object):
         self.obj_root = None
         self.env = {}
         self.compile_flags = []
+        self.library_paths = []
         self.link_flags = []
         self.use_system_lib = False
         self.use_clang_verify = False
@@ -366,9 +367,19 @@ class Configuration(object):
         # Configure extra compiler flags.
         self.compile_flags += ['-I' + self.src_root + '/include',
                                '-I' + self.src_root + '/test/support']
+        if sys.platform == 'linux2':
+            self.compile_flags += ['-D__STDC_FORMAT_MACROS',
+                                   '-D__STDC_LIMIT_MACROS',
+                                   '-D__STDC_CONSTANT_MACROS']
 
     def configure_link_flags(self):
-        self.link_flags += ['-L' + self.obj_root + '/lib', '-lc++']
+        # Configure library search paths
+        lpaths = self.get_lit_conf('library_paths', '').split(';')
+        lpaths = [l for l in lpaths if l.strip()]
+        self.link_flags += ['-L' + self.obj_root + '/lib']
+        self.link_flags += ['-L' + l for l in lpaths]
+        # Configure libraries
+        self.link_flags += ['-lc++']
         link_flags_str = self.get_lit_conf('link_flags')
         if link_flags_str is None:
             cxx_abi = self.get_lit_conf('cxx_abi', 'libcxxabi')
@@ -394,22 +405,18 @@ class Configuration(object):
             elif sys.platform.startswith('freebsd'):
                 self.link_flags += ['-lc', '-lm', '-pthread', '-lgcc_s']
             else:
-                self.lit_config.fatal("unrecognized system")
+                self.lit_config.fatal("unrecognized system: %r" % sys.platform)
 
             self.lit_config.note(
                 "inferred link_flags as: %r" % self.link_flags)
         if link_flags_str:
             self.link_flags += shlex.split(link_flags_str)
 
-        if sys.platform == 'linux2':
-            if not self.use_system_lib:
-                self.link_flags += ['-Wl,-R', self.obj_root + '/lib']
-            self.compile_flags += ['-D__STDC_FORMAT_MACROS',
-                                   '-D__STDC_LIMIT_MACROS',
-                                   '-D__STDC_CONSTANT_MACROS']
-        elif sys.platform.startswith('freebsd'):
-            if not self.use_system_lib:
-                self.link_flags += ['-Wl,-R', self.obj_root + '/lib']
+        # Configure library runtime search paths
+        if not self.use_system_lib:
+            self.link_flags += ['-Wl,-rpath', '-Wl,' + self.obj_root + '/lib']
+        for l in lpaths:
+            self.link_flags += ['-Wl,-rpath', '-Wl,' + l]
 
     def configure_std_flag(self):
         # Try and get the std version from the command line. Fall back to

Modified: libcxx/trunk/test/lit.site.cfg.in
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/lit.site.cfg.in?rev=220118&r1=220117&r2=220118&view=diff
==============================================================================
--- libcxx/trunk/test/lit.site.cfg.in (original)
+++ libcxx/trunk/test/lit.site.cfg.in Fri Oct 17 20:15:17 2014
@@ -7,6 +7,7 @@ config.python_executable     = "@PYTHON_
 config.enable_shared         = @LIBCXX_ENABLE_SHARED@
 config.cxx_abi               = "@LIBCXX_CXX_ABI_LIBNAME@"
 config.llvm_use_sanitizer    = "@LLVM_USE_SANITIZER@"
+config.library_paths         = "@CMAKE_LIBRARY_PATH@"
 
 # Let the main config do the real work.
 lit_config.load_config(config, "@LIBCXX_SOURCE_DIR@/test/lit.cfg")

Modified: libcxx/trunk/www/index.html
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/index.html?rev=220118&r1=220117&r2=220118&view=diff
==============================================================================
--- libcxx/trunk/www/index.html (original)
+++ libcxx/trunk/www/index.html Fri Oct 17 20:15:17 2014
@@ -437,6 +437,36 @@ End of search list.
   </p>
 
   <!--=====================================================================-->
+  <h2 id="local-abi">Using a local ABI library</h2>
+  <!--=====================================================================-->
+  <p>
+    <strong>Note: This is not recommended in almost all cases.</strong><br>
+    Generally these instructions should only be used when you can't install
+    your ABI library.
+  </p>
+  <p>
+    Normally you must link libc++ against a ABI shared library that the
+    linker can find.  If you want to build and test libc++ against an ABI
+    library not in the linker's path you need to set
+    <code>-DCMAKE_LIBRARY_PATH=/path/to/abi/lib</code> when configuring CMake.
+  </p>
+  <p>
+    An example build using libc++abi would look like:
+    <ul>
+    <li><code>CC=clang CXX=clang++ cmake
+              -DLIBCXX_CXX_ABI=libc++abi
+              -DLIBCXX_LIBCXXABI_INCLUDE_PATHS="/path/to/libcxxabi/include"
+              -DCMAKE_LIBRARY_PATH="/path/to/libcxxabi-build/lib"
+              path/to/libcxx</code></li>
+    <li><code>make</code></li>
+    </ul>
+  </p>
+  <p>
+    When testing libc++ LIT will automatically link against the proper ABI
+    library.
+  </p>
+
+  <!--=====================================================================-->
   <h2>Design Documents</h2>
   <!--=====================================================================-->
 





More information about the cfe-commits mailing list