Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -84,104 +84,11 @@ ) 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 Index: cmake/Modules/HandleLibCXXABI.cmake =================================================================== --- /dev/null +++ cmake/Modules/HandleLibCXXABI.cmake @@ -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 Index: test/lit.cfg =================================================================== --- test/lit.cfg +++ test/lit.cfg @@ -197,6 +197,7 @@ 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 @@ # 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 @@ 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 Index: test/lit.site.cfg.in =================================================================== --- test/lit.site.cfg.in +++ test/lit.site.cfg.in @@ -7,6 +7,7 @@ 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") Index: www/index.html =================================================================== --- www/index.html +++ www/index.html @@ -437,6 +437,36 @@

+

Using a local ABI library

+ +

+ Note: This is not recommended in almost all cases.
+ Generally these instructions should only be used when you can't install + your ABI library. +

+

+ 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 + -DCMAKE_LIBRARY_PATH=/path/to/abi/lib when configuring CMake. +

+

+ An example build using libc++abi would look like: +

+

+

+ When testing libc++ LIT will automatically link against the proper ABI + library. +

+ +

Design Documents