beanz created this revision.
beanz added reviewers: zturner, tfiala.
beanz added a subscriber: lldb-commits.
Herald added subscribers: mgorny, beanz.

This patch adds a CMake option LLDB_BUILD_FRAMEWORK, which builds libLLDB as a 
macOS framework instead of as a *nix shared library.

With this patch any LLDB executable that has the INCLUDE_IN_FRAMEWORK option 
set will be built into the Framework's resources directory, and a symlink to 
the exeuctable will be placed under the build directory's bin folder. Creating 
the symlinks allows users to run commands from the build directory without 
altering the workflow.

The framework generated by this patch passes the LLDB test suite, but has not 
been tested beyond that. It is not expected to be fully ready to ship, but it 
is a first step.

With this patch binaries that are placed inside the framework aren't being 
properly installed. Fixing that would increase the patch size significantly, so 
I'd like to do that in a follow-up.

https://reviews.llvm.org/D24749

Files:
  CMakeLists.txt
  cmake/LLDBDependencies.cmake
  cmake/modules/AddLLDB.cmake
  cmake/modules/LLDBConfig.cmake
  scripts/CMakeLists.txt
  scripts/Python/finishSwigPythonLLDB.py
  source/API/CMakeLists.txt
  tools/argdumper/CMakeLists.txt
  tools/darwin-debug/CMakeLists.txt
  tools/debugserver/source/MacOSX/CMakeLists.txt
  tools/lldb-server/CMakeLists.txt

Index: tools/lldb-server/CMakeLists.txt
===================================================================
--- tools/lldb-server/CMakeLists.txt
+++ tools/lldb-server/CMakeLists.txt
@@ -25,7 +25,7 @@
 
 include(../../cmake/LLDBDependencies.cmake)
 
-add_lldb_executable(lldb-server
+add_lldb_executable(lldb-server INCLUDE_IN_FRAMEWORK
     Acceptor.cpp
     lldb-gdbserver.cpp
     lldb-platform.cpp
Index: tools/debugserver/source/MacOSX/CMakeLists.txt
===================================================================
--- tools/debugserver/source/MacOSX/CMakeLists.txt
+++ tools/debugserver/source/MacOSX/CMakeLists.txt
@@ -36,7 +36,7 @@
   lldbDebugserverMacOSX_DarwinLog
   )
 
-add_lldb_executable(debugserver
+add_lldb_executable(debugserver INCLUDE_IN_FRAMEWORK
   HasAVX.s
   CFBundle.cpp
   CFString.cpp
@@ -69,23 +69,14 @@
     OUTPUT_STRIP_TRAILING_WHITESPACE
     OUTPUT_VARIABLE CODESIGN_ALLOCATE
     )
-  # Older cmake versions don't support "-E env".
-  if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 3.2)
-    add_custom_command(TARGET debugserver
-      POST_BUILD
-      # Note: --entitlements option removed, as it causes errors when debugging.
-      # was: COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --entitlements ${CMAKE_CURRENT_SOURCE_DIR}/../debugserver-entitlements.plist --force --sign ${LLDB_CODESIGN_IDENTITY} debugserver
-      COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --force --sign ${LLDB_CODESIGN_IDENTITY} debugserver
-      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
-    )
-  else()
-    add_custom_command(TARGET debugserver
-      POST_BUILD
-      # Note: --entitlements option removed (see comment above).
-      COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --force --sign ${LLDB_CODESIGN_IDENTITY} debugserver
-      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
-    )
-  endif()
+  add_custom_command(TARGET debugserver
+    POST_BUILD
+    # Note: --entitlements option removed (see comment above).
+    COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE}
+            codesign --force --sign ${LLDB_CODESIGN_IDENTITY}
+            $<TARGET_FILE:debugserver>
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
+  )
 endif()
 
 install(TARGETS debugserver
Index: tools/darwin-debug/CMakeLists.txt
===================================================================
--- tools/darwin-debug/CMakeLists.txt
+++ tools/darwin-debug/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_lldb_executable(lldb-launcher
+add_lldb_executable(lldb-launcher INCLUDE_IN_FRAMEWORK
   darwin-debug.cpp
   )
 
Index: tools/argdumper/CMakeLists.txt
===================================================================
--- tools/argdumper/CMakeLists.txt
+++ tools/argdumper/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_lldb_executable(lldb-argdumper
+add_lldb_executable(lldb-argdumper INCLUDE_IN_FRAMEWORK
   argdumper.cpp
   )
 
Index: source/API/CMakeLists.txt
===================================================================
--- source/API/CMakeLists.txt
+++ source/API/CMakeLists.txt
@@ -6,6 +6,12 @@
 # for liblldb to link against
 include(${LLDB_PROJECT_ROOT}/cmake/LLDBDependencies.cmake)
 
+option(LLDB_BUILD_FRAMEWORK "Build the Darwin LLDB.framework" Off)
+
+if (LLDB_BUILD_FRAMEWORK AND NOT APPLE)
+  message(FATAL_ERROR "LLDB.framework cannot be generated unless targeting Apple platforms.")
+endif()
+
 add_lldb_library(liblldb SHARED
   SBAddress.cpp
   SBAttachInfo.cpp
@@ -120,3 +126,11 @@
 endif()
 target_link_libraries(liblldb PRIVATE ${LLDB_SYSTEM_LIBS})
 
+if(LLDB_BUILD_FRAMEWORK)
+  set_target_properties(liblldb PROPERTIES
+    OUTPUT_NAME LLDB
+    FRAMEWORK On
+    FRAMEWORK_VERSION ${LLDB_FRAMEWORK_VERSION}
+    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LLDB_FRAMEWORK_INSTALL_DIR})
+endif()
+
Index: scripts/Python/finishSwigPythonLLDB.py
===================================================================
--- scripts/Python/finishSwigPythonLLDB.py
+++ scripts/Python/finishSwigPythonLLDB.py
@@ -383,7 +383,7 @@
     bMakeFileCalled = "-m" in vDictArgs
     eOSType = utilsOsType.determine_os_type()
     if not bMakeFileCalled:
-        return (bOk, strErrMsg)
+        strBuildDir = os.path.join("..", "..", "..")
     else:
         # Resolve vstrSrcFile path relatively the build directory
         if eOSType == utilsOsType.EnumOsType.Windows:
@@ -394,7 +394,7 @@
             # On a UNIX style platform the vstrFrameworkPythonDir looks like:
             # llvm/build/lib/python2.7/site-packages/lldb
             strBuildDir = os.path.join("..", "..", "..", "..")
-        strSrc = os.path.normcase(os.path.join(strBuildDir, vstrSrcFile))
+    strSrc = os.path.normcase(os.path.join(strBuildDir, vstrSrcFile))
 
     return make_symlink_native(vDictArgs, strSrc, strTarget)
 
@@ -434,7 +434,7 @@
 
     bMakeFileCalled = "-m" in vDictArgs
     if not bMakeFileCalled:
-        strSrc = os.path.join(vstrLldbLibDir, "LLDB")
+        strSrc = "LLDB"
     else:
         strLibFileExtn = ""
         if eOSType == utilsOsType.EnumOsType.Windows:
@@ -724,7 +724,7 @@
         # We are being built by XCode, so all the lldb Python files can go
         # into the LLDB.framework/Resources/Python subdirectory.
         strWkDir = vDictArgs["--targetDir"]
-        strWkDir += os.path.join(strWkDir, "LLDB.framework")
+        strWkDir = os.path.join(strWkDir, "LLDB.framework")
         if os.path.exists(strWkDir):
             if bDbg:
                 print((strMsgFoundLldbFrameWkDir % strWkDir))
Index: scripts/CMakeLists.txt
===================================================================
--- scripts/CMakeLists.txt
+++ scripts/CMakeLists.txt
@@ -11,28 +11,45 @@
 
 include(FindPythonInterp)
 
+set(SWIG_PYTHON_DIR
+  ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
+set(SWIG_INSTALL_DIR lib${LLVM_LIBDIR_SUFFIX})
+
+# Generating the LLDB framework correctly is a bit complicated because the
+# framework depends on the swig output.
+if(LLDB_BUILD_FRAMEWORK)
+  set(framework_arg --framework --target-platform Darwin)
+  set(SWIG_PYTHON_DIR
+    ${LLDB_PYTHON_TARGET_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}/Python)
+  set(SWIG_INSTALL_DIR
+    ${LLDB_FRAMEWORK_INSTALL_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR})
+endif()
+
 find_package(SWIG REQUIRED)
 add_custom_command(
-  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp
+  OUTPUT ${LLDB_WRAP_PYTHON}
   OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lldb.py
   DEPENDS ${SWIG_SOURCES}
   DEPENDS ${SWIG_INTERFACES}
   DEPENDS ${SWIG_HEADERS}
   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Python/prepare_binding_Python.py
   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Python/modify-python-lldb.py
-  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/prepare_bindings.py "--srcRoot=${LLDB_SOURCE_DIR}" "--targetDir=${CMAKE_CURRENT_BINARY_DIR}" "--cfgBldDir=${CMAKE_CURRENT_BINARY_DIR}" "--prefix=${CMAKE_BINARY_DIR}" "--swigExecutable=${SWIG_EXECUTABLE}"
+  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/prepare_bindings.py
+          ${framework_arg}
+          "--srcRoot=${LLDB_SOURCE_DIR}"
+          "--targetDir=${LLDB_PYTHON_TARGET_DIR}"
+          "--cfgBldDir=${CMAKE_CURRENT_BINARY_DIR}"
+          "--prefix=${CMAKE_BINARY_DIR}"
+          "--swigExecutable=${SWIG_EXECUTABLE}"
   COMMENT "Python script building LLDB Python wrapper")
-set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp PROPERTIES GENERATED 1)
+set_source_files_properties(${LLDB_WRAP_PYTHON} PROPERTIES GENERATED 1)
 set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/lldb.py PROPERTIES GENERATED 1)
 
-add_custom_target(swig_wrapper ALL
-  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp
-  )
+add_custom_target(swig_wrapper ALL DEPENDS ${LLDB_WRAP_PYTHON})
 
 # Install the LLDB python module on all operating systems (except Windows)
 if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
-  install(DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}
-  DESTINATION lib${LLVM_LIBDIR_SUFFIX})
+  install(DIRECTORY ${SWIG_PYTHON_DIR} DESTINATION ${SWIG_INSTALL_DIR})
 endif()
 
 # build Python modules
Index: cmake/modules/LLDBConfig.cmake
===================================================================
--- cmake/modules/LLDBConfig.cmake
+++ cmake/modules/LLDBConfig.cmake
@@ -299,6 +299,11 @@
   find_library(SECURITY_LIBRARY Security)
   find_library(DEBUG_SYMBOLS_LIBRARY DebugSymbols PATHS "/System/Library/PrivateFrameworks")
 
+  set(LLDB_FRAMEWORK_INSTALL_DIR Library/Frameworks CACHE STRING "Output directory for LLDB.framework")
+  set(LLDB_FRAMEWORK_VERSION A CACHE STRING "LLDB.framework version (default is A)")
+  set(LLDB_FRAMEWORK_RESOURCE_DIR
+    LLDB.framework/Versions/${LLDB_FRAMEWORK_VERSION}/Resources)
+
   add_definitions( -DLIBXML2_DEFINED )
   list(APPEND system_libs xml2 ${CURSES_LIBRARIES})
   list(APPEND system_libs ${CARBON_LIBRARY} ${FOUNDATION_LIBRARY}
Index: cmake/modules/AddLLDB.cmake
===================================================================
--- cmake/modules/AddLLDB.cmake
+++ cmake/modules/AddLLDB.cmake
@@ -72,10 +72,14 @@
 
     if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "liblldb")
       if (PARAM_SHARED)
+        set(out_dir lib${LLVM_LIBDIR_SUFFIX})
+        if(${name} STREQUAL "liblldb" AND LLDB_BUILD_FRAMEWORK)
+          set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR})
+        endif()
         install(TARGETS ${name}
           RUNTIME DESTINATION bin
-          LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
-          ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
+          LIBRARY DESTINATION ${out_dir}
+          ARCHIVE DESTINATION ${out_dir})
       else()
         install(TARGETS ${name}
           LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
@@ -93,8 +97,25 @@
 endmacro(add_lldb_library)
 
 macro(add_lldb_executable name)
-  add_llvm_executable(${name} DISABLE_LLVM_LINK_LLVM_DYLIB ${ARGN})
-  set_target_properties(${name} PROPERTIES FOLDER "lldb executables")
+  cmake_parse_arguments(ARG "INCLUDE_IN_FRAMEWORK" "" "" ${ARGN})
+  add_llvm_executable(${name} DISABLE_LLVM_LINK_LLVM_DYLIB ${ARG_UNPARSED_ARGUMENTS})
+  set_target_properties(${name} PROPERTIES
+    FOLDER "lldb executables")
+
+  if(LLDB_BUILD_FRAMEWORK)
+    if(ARG_INCLUDE_IN_FRAMEWORK)
+      set_target_properties(${name} PROPERTIES
+            RUNTIME_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:liblldb>/Resources)
+      string(REGEX REPLACE "[^/]+" ".." _dots ${LLDB_FRAMEWORK_INSTALL_DIR})
+      set_property(TARGET ${name} APPEND_STRING PROPERTY
+                   LINK_FLAGS " -rpath @loader_path/../../../../${_dots}/${LLDB_FRAMEWORK_INSTALL_DIR}")
+
+      add_llvm_tool_symlink(${name} $<TARGET_FILE:${name}> ARG_ALWAYS_GENERATE)
+    else()
+      set_property(TARGET ${name} APPEND_STRING PROPERTY
+                   LINK_FLAGS " -rpath @loader_path/../${LLDB_FRAMEWORK_INSTALL_DIR}")
+    endif()
+  endif()
 endmacro(add_lldb_executable)
 
 # Support appending linker flags to an existing target.
Index: cmake/LLDBDependencies.cmake
===================================================================
--- cmake/LLDBDependencies.cmake
+++ cmake/LLDBDependencies.cmake
@@ -209,8 +209,6 @@
   )
 
 if ( NOT LLDB_DISABLE_PYTHON )
-  set(LLDB_WRAP_PYTHON ${LLDB_BINARY_DIR}/scripts/LLDBWrapPython.cpp)
-
   set_source_files_properties(${LLDB_WRAP_PYTHON} PROPERTIES GENERATED 1)
   if (CLANG_CL)
     set_source_files_properties(${LLDB_WRAP_PYTHON} PROPERTIES COMPILE_FLAGS -Wno-unused-function)
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -20,6 +20,16 @@
 # add_subdirectory(include)
 add_subdirectory(docs)
 if (NOT LLDB_DISABLE_PYTHON)
+  set(LLDB_PYTHON_TARGET_DIR ${LLDB_BINARY_DIR}/scripts)
+  if(LLDB_BUILD_FRAMEWORK)
+    set(LLDB_PYTHON_TARGET_DIR
+      ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${LLDB_FRAMEWORK_INSTALL_DIR})
+  else()
+    # Don't set -m when building the framework.
+    set(FINISH_EXTRA_ARGS "-m")
+  endif()
+  set(LLDB_WRAP_PYTHON ${LLDB_PYTHON_TARGET_DIR}/LLDBWrapPython.cpp)
+
   add_subdirectory(scripts)
 endif ()
 add_subdirectory(source)
@@ -31,7 +41,13 @@
 if (NOT LLDB_DISABLE_PYTHON)
     # Add a Post-Build Event to copy over Python files and create the symlink to liblldb.so for the Python API(hardlink on Windows)
     add_custom_target( finish_swig ALL
-        COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py "--srcRoot=${LLDB_SOURCE_DIR}" "--targetDir=${CMAKE_CURRENT_BINARY_DIR}/scripts" "--cfgBldDir=${CMAKE_CURRENT_BINARY_DIR}/scripts" "--prefix=${CMAKE_BINARY_DIR}" "--cmakeBuildConfiguration=${CMAKE_CFG_INTDIR}" "--lldbLibDir=lib${LLVM_LIBDIR_SUFFIX}" -m
+        COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py
+        "--srcRoot=${LLDB_SOURCE_DIR}"
+        "--targetDir=${LLDB_PYTHON_TARGET_DIR}"
+        "--cfgBldDir=${CMAKE_CURRENT_BINARY_DIR}/scripts"
+        "--prefix=${CMAKE_BINARY_DIR}"
+        "--cmakeBuildConfiguration=${CMAKE_CFG_INTDIR}"
+        "--lldbLibDir=lib${LLVM_LIBDIR_SUFFIX}" ${FINISH_EXTRA_ARGS}
         DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py
         DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/scripts/lldb.py
         COMMENT "Python script sym-linking LLDB Python API")
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to