From 1cd196e7b46e49d170a4b4013879a577dee59cb2 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Mon, 16 Jan 2017 20:47:35 +0000 Subject: [PATCH] Improve CMake and LIT support for Windows This patch contains multiple cleanups and fixes to better support building on Windows. * [Test] Fix handling of library runtime search paths by correctly adding them to the PATH variable when running the tests. * [Test] Don't explicitly force "--target=i686-pc-windows" when running the test suite. Clang++ seems to deduce the correct target. * [Test] Fix `.sh.cpp` tests on Windows by properly escaping flags used in shell commands. Specifically windows style paths which included spaces were causing these tests to fail. * [CMake] Add "vcruntime" to the list of supported C++ ABI libraries in CMake, and teach the test suite how to handle it. For now libc++ defaults to using "vcruntime" on Windows except when libc++abi is in tree; That is probably a bug and should be changed to always use vcruntime, at least for now. * [Misc] Move the "c++-build" include directory to the libc++ binary dir instead of the top level project dir and rename it "c++build". This is just misc cleanup. Libc++ shouldn't be creating internal build files and directories at the top-level projects root. * [Misc] Build type_info's destructor when building for MSVC. This is a temporary work around to prevent link errors until we have a proper type_info implementation. llvm-svn: 292157 --- libcxx/CMakeLists.txt | 8 ++++-- libcxx/cmake/Modules/HandleLibCXXABI.cmake | 14 ++++++---- libcxx/src/typeinfo.cpp | 3 +- libcxx/test/libcxx/test/config.py | 32 ++++++++++++++-------- libcxx/test/libcxx/test/format.py | 1 + 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 8174e758d88b..dc7cc467c2eb 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -104,7 +104,7 @@ endif() # ABI Library options --------------------------------------------------------- set(LIBCXX_CXX_ABI "default" CACHE STRING "Specify C++ ABI library to use.") -set(CXXABIS none default libcxxabi libcxxrt libstdc++ libsupc++) +set(CXXABIS none default libcxxabi libcxxrt libstdc++ libsupc++ vcruntime) set_property(CACHE LIBCXX_CXX_ABI PROPERTY STRINGS ;${CXXABIS}) # FIXME: This is a temporary hack to force LLVM buildbots to store @@ -131,9 +131,9 @@ if (LIBCXX_CXX_ABI STREQUAL "default") set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_LIBCXXABI_INCLUDES_INTERNAL}") set(LIBCXX_CXX_ABI_INTREE 1) else() - if (WIN32 AND NOT MINGW) + if (LIBCXX_TARGETING_MSVC) # FIXME: Figure out how to configure the ABI library on Windows. - set(LIBCXX_CXX_ABI_LIBNAME "none") + set(LIBCXX_CXX_ABI_LIBNAME "vcruntime") else() set(LIBCXX_CXX_ABI_LIBNAME "default") endif() @@ -331,7 +331,9 @@ endif() set(LIBCXX_COMPILER ${CMAKE_CXX_COMPILER}) set(LIBCXX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(LIBCXX_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) +set(LIBCXX_BINARY_INCLUDE_DIR "${LIBCXX_BINARY_DIR}/include/c++build") set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX}) +file(MAKE_DIRECTORY "${LIBCXX_BINARY_INCLUDE_DIR}") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR}) diff --git a/libcxx/cmake/Modules/HandleLibCXXABI.cmake b/libcxx/cmake/Modules/HandleLibCXXABI.cmake index 4a6382b136b8..182565f52d22 100644 --- a/libcxx/cmake/Modules/HandleLibCXXABI.cmake +++ b/libcxx/cmake/Modules/HandleLibCXXABI.cmake @@ -18,6 +18,7 @@ # abidirs : A list of relative paths to create under an include directory # in the libc++ build directory. # + macro(setup_abi_lib abidefines abilib abifiles abidirs) list(APPEND LIBCXX_COMPILE_FLAGS ${abidefines}) set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_CXX_ABI_INCLUDE_PATHS}" @@ -32,11 +33,10 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs) set(LIBCXX_ABILIB_FILES ${abifiles}) # The place in the build tree where we store out-of-source headers. - set(LIBCXX_BUILD_HEADERS_ROOT "${CMAKE_BINARY_DIR}/include/c++-build") file(MAKE_DIRECTORY "${LIBCXX_BUILD_HEADERS_ROOT}") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include/c++/v1") foreach(_d ${abidirs}) - file(MAKE_DIRECTORY "${LIBCXX_BUILD_HEADERS_ROOT}/${_d}") + file(MAKE_DIRECTORY "${LIBCXX_BINARY_INCLUDE_DIR}/${_d}") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include/c++/v1/${_d}") endforeach() @@ -48,19 +48,19 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs) get_filename_component(dstdir ${fpath} PATH) get_filename_component(ifile ${fpath} NAME) file(COPY "${incpath}/${fpath}" - DESTINATION "${LIBCXX_BUILD_HEADERS_ROOT}/${dstdir}" + DESTINATION "${LIBCXX_BINARY_INCLUDE_DIR}/${dstdir}" ) file(COPY "${incpath}/${fpath}" DESTINATION "${CMAKE_BINARY_DIR}/include/c++/v1/${dstdir}" ) if (LIBCXX_INSTALL_HEADERS) - install(FILES "${LIBCXX_BUILD_HEADERS_ROOT}/${fpath}" + install(FILES "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}" DESTINATION include/c++/v1/${dstdir} COMPONENT libcxx PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) endif() - list(APPEND abilib_headers "${LIBCXX_BUILD_HEADERS_ROOT}/${fpath}") + list(APPEND abilib_headers "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}") endif() endforeach() if (NOT found) @@ -68,7 +68,7 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs) endif() endforeach() - include_directories("${LIBCXX_BUILD_HEADERS_ROOT}") + include_directories("${LIBCXX_BINARY_INCLUDE_DIR}") endmacro() @@ -110,6 +110,8 @@ elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxrt") setup_abi_lib("-DLIBCXXRT" "cxxrt" "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h" "" ) +elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "vcruntime") + # Nothing TODO elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "none") list(APPEND LIBCXX_COMPILE_FLAGS "-D_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY") elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "default") diff --git a/libcxx/src/typeinfo.cpp b/libcxx/src/typeinfo.cpp index d0a7dae38025..8123606b161a 100644 --- a/libcxx/src/typeinfo.cpp +++ b/libcxx/src/typeinfo.cpp @@ -15,7 +15,8 @@ #include "typeinfo" -#if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) +#if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) || \ + defined(_LIBCPP_ABI_MICROSOFT) // FIXME: This is a temporary workaround std::type_info::~type_info() { } diff --git a/libcxx/test/libcxx/test/config.py b/libcxx/test/libcxx/test/config.py index 2478bacb2144..6b4afbc79997 100644 --- a/libcxx/test/libcxx/test/config.py +++ b/libcxx/test/libcxx/test/config.py @@ -11,6 +11,7 @@ import locale import os import platform import pkgutil +import pipes import re import shlex import shutil @@ -218,8 +219,7 @@ class Configuration(object): def _configure_clang_cl(self, clang_path): assert self.cxx_is_clang_cl - # FIXME: don't hardcode the target - flags = ['--target=i686-pc-windows'] + flags = [] compile_flags = [] link_flags = [] if 'INCLUDE' in os.environ: @@ -227,8 +227,12 @@ class Configuration(object): for p in os.environ['INCLUDE'].split(';') if p.strip()] if 'LIB' in os.environ: - link_flags += ['-L%s' % p.strip() - for p in os.environ['LIB'].split(';') if p.strip()] + for p in os.environ['LIB'].split(';'): + p = p.strip() + if not p: + continue + link_flags += ['-L%s' % p] + self.add_path(self.exec_env, p) return CXXCompiler(clang_path, flags=flags, compile_flags=compile_flags, link_flags=link_flags) @@ -472,7 +476,7 @@ class Configuration(object): self.cxx.compile_flags += ['-I' + cxx_headers] if self.libcxx_obj_root is not None: cxxabi_headers = os.path.join(self.libcxx_obj_root, 'include', - 'c++-build') + 'c++build') if os.path.isdir(cxxabi_headers): self.cxx.compile_flags += ['-I' + cxxabi_headers] @@ -677,6 +681,10 @@ class Configuration(object): self.cxx.link_flags += ['-lc++abi'] elif cxx_abi == 'libcxxrt': self.cxx.link_flags += ['-lcxxrt'] + elif cxx_abi == 'vcruntime': + debug_suffix = 'd' if self.debug_build else '' + self.cxx.link_flags += ['-l%s%s' % (lib, debug_suffix) for lib in + ['vcruntime', 'ucrt', 'msvcrt']] elif cxx_abi == 'none' or cxx_abi == 'default': if self.is_windows: debug_suffix = 'd' if self.debug_build else '' @@ -854,9 +862,9 @@ class Configuration(object): # Configure compiler substitutions sub.append(('%cxx', self.cxx.path)) # Configure flags substitutions - flags_str = ' '.join(self.cxx.flags) - compile_flags_str = ' '.join(self.cxx.compile_flags) - link_flags_str = ' '.join(self.cxx.link_flags) + flags_str = ' '.join([pipes.quote(f) for f in self.cxx.flags]) + compile_flags_str = ' '.join([pipes.quote(f) for f in self.cxx.compile_flags]) + link_flags_str = ' '.join([pipes.quote(f) for f in self.cxx.link_flags]) all_flags = '%s %s %s' % (flags_str, compile_flags_str, link_flags_str) sub.append(('%flags', flags_str)) sub.append(('%compile_flags', compile_flags_str)) @@ -883,9 +891,11 @@ class Configuration(object): sub.append(('%link', link_str)) sub.append(('%build', build_str)) # Configure exec prefix substitutions. - exec_env_str = 'env ' if len(self.exec_env) != 0 else '' - for k, v in self.exec_env.items(): - exec_env_str += ' %s=%s' % (k, v) + exec_env_str = '' + if not self.is_windows and len(self.exec_env) != 0: + exec_env_str = 'env ' + for k, v in self.exec_env.items(): + exec_env_str += ' %s=%s' % (k, v) # Configure run env substitution. exec_str = exec_env_str if self.lit_config.useValgrind: diff --git a/libcxx/test/libcxx/test/format.py b/libcxx/test/libcxx/test/format.py index f267cab59e91..e87a8a5bd7d4 100644 --- a/libcxx/test/libcxx/test/format.py +++ b/libcxx/test/libcxx/test/format.py @@ -140,6 +140,7 @@ class LibcxxTestFormat(object): # We can't run ShTest tests with a executor yet. # For now, bail on trying to run them return lit.Test.UNSUPPORTED, 'ShTest format not yet supported' + test.config.enviroment = dict(self.exec_env) return lit.TestRunner._runShTest(test, lit_config, self.execute_external, script, tmpBase)