Fix linking of unit tests via CMake on Windows.
authorZachary Turner <zturner@google.com>
Wed, 18 Mar 2015 16:56:24 +0000 (16:56 +0000)
committerZachary Turner <zturner@google.com>
Wed, 18 Mar 2015 16:56:24 +0000 (16:56 +0000)
A previous attempt to make the unit tests link properly on
Linux broke it for Windows.  This patch fixes it for both platforms.

llvm-svn: 232648

13 files changed:
lldb/cmake/LLDBDependencies.cmake
lldb/cmake/modules/AddLLDB.cmake
lldb/include/lldb/Host/msvc/Config.h
lldb/source/API/CMakeLists.txt
lldb/source/CMakeLists.txt
lldb/unittests/CMakeLists.txt
lldb/unittests/Host/CMakeLists.txt
lldb/unittests/Host/SocketTestMock.cpp [deleted file]
lldb/unittests/Interpreter/CMakeLists.txt
lldb/unittests/Plugins/Process/Linux/CMakeLists.txt
lldb/unittests/Plugins/Process/Linux/ThreadStateCoordinatorTestMock.cpp [deleted file]
lldb/unittests/Utility/CMakeLists.txt
lldb/unittests/gtest_common.h

index 4af457f..5aff968 100644 (file)
@@ -1,4 +1,5 @@
 set( LLDB_USED_LIBS
+  lldbBase
   lldbBreakpoint
   lldbCommands
   lldbDataFormatters
index 5c1a181..3bf2688 100644 (file)
@@ -1,78 +1,95 @@
-macro(add_lldb_library name)\r
-  # only supported parameters to this macro are the optional \r
-  # MODULE;SHARED;STATIC library type and source files\r
-  cmake_parse_arguments(PARAM\r
-    "MODULE;SHARED;STATIC;OBJECT"\r
-    ""\r
-    ""\r
-    ${ARGN})\r
-  llvm_process_sources(srcs ${PARAM_UNPARSED_ARGUMENTS})\r
-\r
-  if (MSVC_IDE OR XCODE)\r
-    string(REGEX MATCHALL "/[^/]+" split_path ${CMAKE_CURRENT_SOURCE_DIR})\r
-    list(GET split_path -1 dir)\r
-    file(GLOB_RECURSE headers\r
-      ../../include/lldb${dir}/*.h)\r
-    set(srcs ${srcs} ${headers})\r
-  endif()\r
-  if (PARAM_MODULE)\r
-    set(libkind MODULE)\r
-  elseif (PARAM_SHARED)\r
-    set(libkind SHARED)\r
-  elseif (PARAM_STATIC)\r
-    set(libkind STATIC)\r
-  elseif (PARAM_OBJECT)\r
-    set(libkind OBJECT)\r
-  else ()\r
-    # library type unspecified - controlled by BUILD_SHARED_LIBS\r
-    unset(libkind)\r
-  endif()\r
-\r
-  #PIC not needed on Win\r
-  if (NOT MSVC)\r
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")\r
-  endif()\r
-\r
-  if (PARAM_OBJECT)\r
-    add_library(${name} ${libkind} ${srcs})\r
-  else()\r
-    llvm_add_library(${name} ${libkind} ${srcs})\r
-\r
-    if (PARAM_STATIC)\r
-      set(lldb_library_keyword ${cmake_2_8_12_INTERFACE})\r
-    else ()\r
-      set(lldb_library_keyword ${cmake_2_8_12_PUBLIC})\r
-    endif ()\r
-\r
-    if(LLDB_USED_LIBS)\r
-      # The Darwin linker doesn't understand --start-group/--end-group.\r
-      if (LLVM_COMPILER_IS_GCC_COMPATIBLE AND NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")\r
-        target_link_libraries(${name} ${lldb_library_keyword}\r
-                              -Wl,--start-group ${LLDB_USED_LIBS} -Wl,--end-group)\r
-      else()\r
-        target_link_libraries(${name} ${lldb_library_keyword} ${LLDB_USED_LIBS})\r
-      endif()\r
-    endif()\r
-\r
-    target_link_libraries(${name} ${lldb_library_keyword} ${CLANG_USED_LIBS})\r
-    target_link_libraries(${name} ${lldb_library_keyword} ${LLVM_USED_LIBS})\r
-    llvm_config(${name} ${LLVM_LINK_COMPONENTS})\r
-    target_link_libraries(${name} ${lldb_library_keyword} ${LLVM_COMMON_LIBS})\r
-\r
-    install(TARGETS ${name}\r
-      LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}\r
-      ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})\r
-  endif()\r
-\r
-  # Hack: only some LLDB libraries depend on the clang autogenerated headers,\r
-  # but it is simple enough to make all of LLDB depend on some of those\r
-  # headers without negatively impacting much of anything.\r
-  add_dependencies(${name} libclang)\r
-\r
-  set_target_properties(${name} PROPERTIES FOLDER "lldb libraries")\r
-endmacro(add_lldb_library)\r
-\r
-macro(add_lldb_executable name)\r
-  add_llvm_executable(${name} ${ARGN})\r
-  set_target_properties(${name} PROPERTIES FOLDER "lldb executables")\r
-endmacro(add_lldb_executable)\r
+function(lldb_link_common_libs name targetkind)
+  if (NOT LLDB_USED_LIBS)
+    return()
+  endif()
+
+  set(COMPILER_SUPPORTS_GROUPS OFF)
+  if (LLVM_COMPILER_IS_GCC_COMPATIBLE AND NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
+    # The Darwin linker doesn't understand --start-group/--end-group.
+    set(COMPILER_SUPPORTS_GROUPS ON)
+  endif()
+
+  if(${targetkind} MATCHES "SHARED")
+    set(LINK_KEYWORD ${cmake_2_8_12_PUBLIC})
+  endif()
+  
+  if(${targetkind} MATCHES "SHARED" OR ${targetkind} MATCHES "EXE")
+    if (COMPILER_SUPPORTS_GROUPS)
+      target_link_libraries(${name} ${LINK_KEYWORD}
+                            -Wl,--start-group ${LLDB_USED_LIBS} -Wl,--end-group)
+    else()
+      target_link_libraries(${name} ${LINK_KEYWORD} ${LLDB_USED_LIBS})
+    endif()
+  endif()
+endfunction(lldb_link_common_libs)
+
+macro(add_lldb_library name)
+  # only supported parameters to this macro are the optional 
+  # MODULE;SHARED;STATIC library type and source files
+  cmake_parse_arguments(PARAM
+    "MODULE;SHARED;STATIC;OBJECT"
+    ""
+    ""
+    ${ARGN})
+  llvm_process_sources(srcs ${PARAM_UNPARSED_ARGUMENTS})
+
+  if (MSVC_IDE OR XCODE)
+    string(REGEX MATCHALL "/[^/]+" split_path ${CMAKE_CURRENT_SOURCE_DIR})
+    list(GET split_path -1 dir)
+    file(GLOB_RECURSE headers
+      ../../include/lldb${dir}/*.h)
+    set(srcs ${srcs} ${headers})
+  endif()
+  if (PARAM_MODULE)
+    set(libkind MODULE)
+  elseif (PARAM_SHARED)
+    set(libkind SHARED)
+  elseif (PARAM_STATIC)
+    set(libkind STATIC)
+  elseif (PARAM_OBJECT)
+    set(libkind OBJECT)
+  else ()
+    # library type unspecified - controlled by BUILD_SHARED_LIBS
+    unset(libkind)
+  endif()
+
+  #PIC not needed on Win
+  if (NOT MSVC)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
+  endif()
+
+  if (PARAM_OBJECT)
+    add_library(${name} ${libkind} ${srcs})
+  else()
+    llvm_add_library(${name} ${libkind} ${srcs})
+
+    lldb_link_common_libs(${name} "${libkind}")
+
+    
+    target_link_libraries(${name} ${cmake_2_8_12_PUBLIC} ${CLANG_USED_LIBS})
+    llvm_config(${name} ${LLVM_LINK_COMPONENTS})
+
+    if (PARAM_SHARED)
+      install(TARGETS ${name}
+        RUNTIME DESTINATION bin
+        LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+        ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
+    else()
+      install(TARGETS ${name}
+        LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+        ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
+    endif()
+  endif()
+
+  # Hack: only some LLDB libraries depend on the clang autogenerated headers,
+  # but it is simple enough to make all of LLDB depend on some of those
+  # headers without negatively impacting much of anything.
+  add_dependencies(${name} libclang)
+
+  set_target_properties(${name} PROPERTIES FOLDER "lldb libraries")
+endmacro(add_lldb_library)
+
+macro(add_lldb_executable name)
+  add_llvm_executable(${name} ${ARGN})
+  set_target_properties(${name} PROPERTIES FOLDER "lldb executables")
+endmacro(add_lldb_executable)
index bdf404c..4a4ed57 100644 (file)
@@ -14,8 +14,8 @@
 // platform functionality availability.
 //----------------------------------------------------------------------
 
-#ifndef liblldb_Platform_Config_h_
-#define liblldb_Platform_Config_h_
+#ifndef liblldb_host_msvc_Config_h_
+#define liblldb_host_msvc_Config_h_
 
 #define LLDB_DISABLE_POSIX
 
 //#define LLDB_CONFIG_FCNTL_GETPATH_SUPPORTED 1
 
 #if _HAS_EXCEPTIONS == 0
-// Exceptions are disabled so this isn't defined, but concrt assumes it is.
-static void *__uncaught_exception() { return nullptr; }
+// Due to a bug in <thread>, when _HAS_EXCEPTIONS == 0 the header will try to call
+// uncaught_exception() without having a declaration for it.  The fix for this is
+// to manually #include <eh.h>, which contains this declaration.
+#include <eh.h>
 #endif
 
 #endif // #ifndef liblldb_Platform_Config_h_
index a6f4349..d5a85e3 100644 (file)
@@ -4,22 +4,11 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
   add_definitions( -DEXPORT_LIBLLDB )
 endif()
 
-# An OBJECT library is a special type of CMake library that produces
-# no archive, has no link interface, and no link inputs.  It is like
-# a regular archive, just without the physical output.  To link against
-# an OBJECT library, you reference it in the *source* file list of a
-# library using the special syntax $<TARGET_OBJECTS:lldbAPI>.  This will
-# cause every object file to be passed to the linker independently, as
-# opposed to a single archive being passed to the linker.
-#
-# This is *extremely* important on Windows.  lldbAPI exports all of the
-# SB classes using __declspec(dllexport).  Unfortunately for technical
-# reasons it is not possible (well, extremely difficult) to get the linker
-# to propagate a __declspec(dllexport) attribute from a symbol in an
-# object file in an archive to a DLL that links against that archive.
-# The solution to this is for the DLL to link the object file directly.
-# So lldbAPI must be an OBJECT library.
-add_lldb_library(lldbAPI OBJECT
+# Include this so that add_lldb_library() has the list of dependencies
+# for liblldb to link against
+include(${LLDB_PROJECT_ROOT}/cmake/LLDBDependencies.cmake)
+
+add_lldb_library(liblldb SHARED
   SBAddress.cpp
   SBAttachInfo.cpp
   SBBlock.cpp
@@ -77,4 +66,30 @@ add_lldb_library(lldbAPI OBJECT
   SBVariablesOptions.cpp
   SBWatchpoint.cpp
   SBUnixSignals.cpp
+  ${LLDB_WRAP_PYTHON}
+  ${LLDB_VERS_GENERATED_FILE}
+  )
+
+set_target_properties(liblldb
+  PROPERTIES
+  VERSION ${LLDB_VERSION}
   )
+
+if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
+  # Only MSVC has the ABI compatibility problem and avoids using FindPythonLibs,
+  # so only it needs to explicitly link against ${PYTHON_LIBRARY}
+  if (MSVC AND NOT LLDB_DISABLE_PYTHON)
+    target_link_libraries(liblldb PRIVATE ${PYTHON_LIBRARY})
+  endif()
+else()
+  set_target_properties(liblldb
+    PROPERTIES
+    OUTPUT_NAME lldb
+    )
+endif()
+
+if (LLDB_WRAP_PYTHON OR LLDB_VERS_GENERATED_FILE)
+  add_dependencies(liblldb swig_wrapper)
+endif()
+target_link_libraries(liblldb ${cmake_2_8_12_PRIVATE} ${LLDB_SYSTEM_LIBS})
+
index 372c38e..cdd46ad 100644 (file)
@@ -25,7 +25,11 @@ include_directories(
   )
 endif ()
 
-add_subdirectory(API)
+add_lldb_library(lldbBase
+  lldb.cpp
+  lldb-log.cpp
+  )
+
 add_subdirectory(Breakpoint)
 add_subdirectory(Commands)
 add_subdirectory(Core)
@@ -38,43 +42,8 @@ add_subdirectory(Symbol)
 add_subdirectory(Target)
 add_subdirectory(Utility)
 
-include(${LLDB_PROJECT_ROOT}/cmake/LLDBDependencies.cmake)
-
-add_lldb_library(lldbBase STATIC
-  lldb.cpp
-  lldb-log.cpp
-  )
-
-add_lldb_library(liblldb SHARED
-  lldb.cpp
-  lldb-log.cpp
-  $<TARGET_OBJECTS:lldbAPI>
-  ${LLDB_WRAP_PYTHON}
-  ${LLDB_VERS_GENERATED_FILE}
-  )
-
-set_target_properties(liblldb
-  PROPERTIES
-  VERSION ${LLDB_VERSION}
-  )
-
-if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
-  # Only MSVC has the ABI compatibility problem and avoids using FindPythonLibs,
-  # so only it needs to explicitly link against ${PYTHON_LIBRARY}
-  if (MSVC AND NOT LLDB_DISABLE_PYTHON)
-    target_link_libraries(liblldb PRIVATE ${PYTHON_LIBRARY})
-  endif()
-else()
-  set_target_properties(liblldb
-    PROPERTIES
-    OUTPUT_NAME lldb
-    )
-endif()
-
-if (LLDB_WRAP_PYTHON OR LLDB_VERS_GENERATED_FILE)
-  add_dependencies(liblldb swig_wrapper)
-endif()
-target_link_libraries(liblldb ${cmake_2_8_12_PRIVATE} ${LLDB_SYSTEM_LIBS})
+# Build API last, since liblldb needs to link against every other target
+add_subdirectory(API)
 
 # Determine LLDB revision and repository. GetSourceVersion and GetRepositoryPath are shell-scripts, and as
 # such will not work on Windows.
@@ -102,7 +71,3 @@ endif ()
 # FIXME: implement svn/git revision and repository parsing solution on Windows. There is an SVN-only
 #        revision parsing solution in tools/clang/lib/Basic/CMakelists.txt.
 
-install(TARGETS liblldb
-  RUNTIME DESTINATION bin
-  LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
-  ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
index 83c535a..3770de5 100644 (file)
@@ -10,11 +10,21 @@ else ()
   list(APPEND LLVM_COMPILE_FLAGS -include ${LLDB_GTEST_COMMON_INCLUDE})
 endif ()
 
-# add_lldb_unittest(test_dirname file1.cpp file2.cpp)
-#
-# Will compile the list of files together and link against
+include(${LLDB_PROJECT_ROOT}/cmake/LLDBDependencies.cmake)
+
 function(add_lldb_unittest test_name)
-  add_unittest(LLDBUnitTests ${test_name} ${ARGN})
+  add_unittest(LLDBUnitTests
+    ${test_name}
+    ${ARGN}
+    )
+
+  if (MSVC)
+    target_link_libraries(${test_name} ${PYTHON_LIBRARY})
+  endif()
+
+  lldb_link_common_libs(${test_name} EXE)
+  target_link_libraries(${test_name} ${CLANG_USED_LIBS})
+  llvm_config(${test_name} ${LLVM_LINK_COMPONENTS})
 endfunction()
 
 add_subdirectory(Host)
index 9d3f498..b03f830 100644 (file)
@@ -1,10 +1,4 @@
 add_lldb_unittest(HostTests
   SocketAddressTest.cpp
   SocketTest.cpp
-  SocketTestMock.cpp
-  )
-
-target_link_libraries(HostTests
-  lldbBase
-  ${PYTHON_LIBRARY}
   )
diff --git a/lldb/unittests/Host/SocketTestMock.cpp b/lldb/unittests/Host/SocketTestMock.cpp
deleted file mode 100644 (file)
index d457c51..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-//===-- SocketTestMock.cpp --------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This file provides a few necessary functions to link SocketTest.cpp
-// Bringing in the real implementations results in a cascade of dependencies
-// that pull in all of lldb.
-
-#include "lldb/Core/Log.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-using namespace lldb_private;
-
-void
-lldb_private::Log::Error (char const*, ...)
-{
-}
-
-void
-lldb_private::Log::Printf (char const*, ...)
-{
-}
-
-Log*
-lldb_private::GetLogIfAnyCategoriesSet (unsigned int)
-{
-    return nullptr;
-}
-
-#include "lldb/Host/FileSystem.h"
-
-#ifdef _WIN32
-
-Error
-FileSystem::Unlink(const char *path)
-{
-    Error error;
-    BOOL result = ::DeleteFile(path);
-    if (!result)
-        error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
-    return error;
-}
-
-#else
-
-Error
-FileSystem::Unlink (const char *path)
-{
-    Error error;
-    if (::unlink (path) == -1)
-        error.SetErrorToErrno ();
-    return error;
-}
-
-#endif
-
index 9f09713..4078476 100644 (file)
@@ -3,6 +3,5 @@ add_lldb_unittest(InterpreterTests
   )
 
 target_link_libraries(InterpreterTests
-  lldbInterpreter
   ${PYTHON_LIBRARY}
   )
index 0acf229..d5bedfb 100644 (file)
@@ -1,9 +1,3 @@
 add_lldb_unittest(ProcessLinuxTests
   ThreadStateCoordinatorTest.cpp
-  ThreadStateCoordinatorTestMock.cpp
-  )
-
-target_link_libraries(ProcessLinuxTests
-  lldbBase
-  ${PYTHON_LIBRARY}
   )
diff --git a/lldb/unittests/Plugins/Process/Linux/ThreadStateCoordinatorTestMock.cpp b/lldb/unittests/Plugins/Process/Linux/ThreadStateCoordinatorTestMock.cpp
deleted file mode 100644 (file)
index 7369360..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//===-- ThreadStateCoordinatorTestMock.cpp ----------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This file provides a few necessary functions to link
-// ThreadStateCoordinatorTest.cpp Bringing in the real implementations results
-// in a cascade of dependencies that pull in all of lldb.
-
-#include "lldb/Core/Log.h"
-
-using namespace lldb_private;
-
-void
-lldb_private::Log::Error (char const*, ...)
-{
-}
-
-void
-lldb_private::Log::Printf (char const*, ...)
-{
-}
-
-Log*
-lldb_private::GetLogIfAnyCategoriesSet (unsigned int)
-{
-    return nullptr;
-}
index 6d711f6..e6cd2a3 100644 (file)
@@ -2,8 +2,3 @@ add_lldb_unittest(UtilityTests
   StringExtractorTest.cpp
   UriParserTest.cpp
   )
-
-target_link_libraries(UtilityTests
-  lldbBase
-  ${PYTHON_LIBRARY}
-  )
index 1fb394a..006c959 100644 (file)
 // units.  Be very leary about putting anything in this file.
 
 #if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// MSVC's STL implementation tries to work well with /EHs-c- and
-// _HAS_EXCEPTIONS=0.  But <thread> in particular doesn't work with it, because
-// it relies on <concrt.h> which tries to throw an exception without checking
-// for _HAS_EXCEPTIONS=0.  This causes the linker to require a definition of
-// __uncaught_exception(), but the STL doesn't define this function when
-// _HAS_EXCEPTIONS=0.  The workaround here is to just provide a stub
-// implementation to get it to link.
-inline bool
-__uncaught_exception()
-{
-    return true;
-}
+// Due to a bug in <thread>, when _HAS_EXCEPTIONS == 0 the header will try to call
+// uncaught_exception() without having a declaration for it.  The fix for this is
+// to manually #include <eh.h>, which contains this declaration.
+#include <eh.h>
 #endif