@@ -518,6 +518,17 @@ set(LLVMDSDL_INSTALLABLE_LIBRARIES
518518
519519set (LLVMDSDL_INSTALL_COMPONENT_BIN "bin" )
520520set (LLVMDSDL_INSTALL_COMPONENT_DEV "dev" )
521+ set (LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT OFF )
522+ if (APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Linux" )
523+ set (LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT ON )
524+ endif ()
525+
526+ option (LLVMDSDL_ENABLE_SELF_CONTAINED_TOOL_BUNDLE
527+ "Enable self-contained tool bundle target (copies the tools with runtime deps)"
528+ ${LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT} )
529+
530+ set (LLVMDSDL_SELF_CONTAINED_TOOLS_DIR "${LLVMDSDL_BINARY_DIR } /self-contained-tools" )
531+
521532
522533# Vendoring libLLVM into the package.
523534#
@@ -527,23 +538,35 @@ set(LLVMDSDL_INSTALL_COMPONENT_DEV "dev")
527538# the library inside the package is what makes `apt install ./llvm-dsdl_*.deb` work
528539# on a machine that has never heard of apt.llvm.org.
529540#
530- # Off by default: a developer's `cmake --install` should not copy a ~100 MB library
541+ # The same reasoning applies to the macOS tarball: a bare download has no
542+ # dependency resolver either, and a tree whose binaries reference
543+ # /opt/homebrew/opt/llvm only runs on a machine that already has Homebrew LLVM.
544+ #
545+ # Off by default: a developer's `cmake --install` should not copy a ~150 MB library
531546# into the install tree. The release build turns it on explicitly.
532547#
533548# LLVM is Apache-2.0-WITH-LLVM-exception, so redistribution is fine with
534549# attribution -- packaging/deb/copyright carries the licence paragraph, and its
535550# Files: stanza must be activated when this is enabled for a published package.
536551option (LLVMDSDL_VENDOR_LLVM
537- "Ship libLLVM inside the install tree and point the tools at it via RPATH ."
552+ "Ship libLLVM inside the install tree so the package runs without a system LLVM ."
538553 OFF )
539554
540- if (LLVMDSDL_VENDOR_LLVM)
541- if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" )
542- message (FATAL_ERROR
543- "LLVMDSDL_VENDOR_LLVM is implemented for Linux only (it relies on ELF RPATH). "
544- "macOS distribution goes through Homebrew, which depends on llvm@22 instead." )
545- endif ()
555+ # Linux and macOS reach the same outcome by different mechanisms: ELF RPATH set
556+ # on the installed binaries, versus Mach-O install names rewritten by the bundle
557+ # target. The flag means "self-contained" on both; only the plumbing differs.
558+ set (LLVMDSDL_VENDOR_LLVM_VIA_BUNDLE OFF )
559+ if (LLVMDSDL_VENDOR_LLVM AND APPLE )
560+ set (LLVMDSDL_VENDOR_LLVM_VIA_BUNDLE ON )
561+ endif ()
562+
563+ if (LLVMDSDL_VENDOR_LLVM AND NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT APPLE )
564+ message (FATAL_ERROR
565+ "LLVMDSDL_VENDOR_LLVM is implemented for Linux (ELF RPATH) and macOS "
566+ "(Mach-O install names) only." )
567+ endif ()
546568
569+ if (LLVMDSDL_VENDOR_LLVM AND CMAKE_SYSTEM_NAME STREQUAL "Linux" )
547570 # A private directory rather than ${CMAKE_INSTALL_LIBDIR}: this is our copy of
548571 # someone else's library, and it must never satisfy anything but our own tools.
549572 set (LLVMDSDL_VENDOR_LLVM_SUBDIR "${CMAKE_INSTALL_LIBDIR} /llvm-dsdl" )
@@ -625,10 +648,39 @@ if(LLVMDSDL_VENDOR_LLVM)
625648 BUILD_WITH_INSTALL_RPATH OFF )
626649endif ()
627650
628- install (
629- TARGETS ${LLVMDSDL_INSTALLABLE_TOOLS}
630- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
631- COMPONENT ${LLVMDSDL_INSTALL_COMPONENT_BIN} )
651+ if (LLVMDSDL_VENDOR_LLVM_VIA_BUNDLE)
652+ # macOS gets its self-contained tree from the bundle target, which rewrites
653+ # Mach-O install names in place. Installing the bundle rather than the raw
654+ # targets is the whole point: the raw binaries reference
655+ # /opt/homebrew/opt/llvm and only run where Homebrew LLVM is already present,
656+ # which is exactly the trap a downloadable tarball must not contain.
657+ #
658+ # The bundle's layout is bin/ + lib/ and its install names are
659+ # @executable_path/../lib, so it must land at the prefix root unchanged --
660+ # relocating lib/ elsewhere would break every reference in it.
661+ if (NOT LLVMDSDL_ENABLE_SELF_CONTAINED_TOOL_BUNDLE)
662+ message (FATAL_ERROR
663+ "LLVMDSDL_VENDOR_LLVM on macOS is implemented via the self-contained bundle, "
664+ "but LLVMDSDL_ENABLE_SELF_CONTAINED_TOOL_BUNDLE is OFF." )
665+ endif ()
666+
667+ install (
668+ DIRECTORY "${LLVMDSDL_SELF_CONTAINED_TOOLS_DIR} /bin/"
669+ DESTINATION "${CMAKE_INSTALL_BINDIR} "
670+ COMPONENT ${LLVMDSDL_INSTALL_COMPONENT_BIN}
671+ USE_SOURCE_PERMISSIONS)
672+
673+ install (
674+ DIRECTORY "${LLVMDSDL_SELF_CONTAINED_TOOLS_DIR} /lib/"
675+ DESTINATION "${CMAKE_INSTALL_LIBDIR} "
676+ COMPONENT ${LLVMDSDL_INSTALL_COMPONENT_BIN}
677+ USE_SOURCE_PERMISSIONS)
678+ else ()
679+ install (
680+ TARGETS ${LLVMDSDL_INSTALLABLE_TOOLS}
681+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
682+ COMPONENT ${LLVMDSDL_INSTALL_COMPONENT_BIN} )
683+ endif ()
632684
633685install (
634686 TARGETS ${LLVMDSDL_INSTALLABLE_LIBRARIES}
@@ -921,27 +973,27 @@ if(LLVMDSDL_ENABLE_PYTHON_ACCELERATOR)
921973 )
922974endif ()
923975
924- set (LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT OFF )
925- if (APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Linux" )
926- set (LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT ON )
927- endif ()
928-
929- option (LLVMDSDL_ENABLE_SELF_CONTAINED_TOOL_BUNDLE
930- "Enable self-contained tool bundle target (copies dsdlc/dsdl-opt with runtime deps)"
931- ${LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT} )
932-
933976if (LLVMDSDL_ENABLE_SELF_CONTAINED_TOOL_BUNDLE)
934- set (LLVMDSDL_SELF_CONTAINED_TOOLS_DIR
935- "${LLVMDSDL_BINARY_DIR } /self-contained-tools" )
936- add_custom_target (bundle -tools-self-contained
977+ # All three tools, not just the two that generate code: the macOS release
978+ # tarball ships this tree, and a package missing the language server would be
979+ # a strange thing to hand someone.
980+ #
981+ # Part of ALL only when the install rules consume it (macOS vendoring), because
982+ # then `cmake --install` must find it already built. Otherwise it stays opt-in:
983+ # it copies and re-signs ~150 MB of LLVM, which no ordinary build should pay for.
984+ set (LLVMDSDL_BUNDLE_IN_ALL "" )
985+ if (LLVMDSDL_VENDOR_LLVM_VIA_BUNDLE)
986+ set (LLVMDSDL_BUNDLE_IN_ALL ALL)
987+ endif ()
988+
989+ add_custom_target (bundle -tools-self-contained ${LLVMDSDL_BUNDLE_IN_ALL}
937990 COMMAND
938991 ${CMAKE_COMMAND }
939- -DTOOL_DSDLC=$<TARGET_FILE:dsdlc>
940- -DTOOL_DSDLOPT=$<TARGET_FILE:dsdl-opt>
992+ "-DTOOLS=$<TARGET_FILE :dsdlc >;$<TARGET_FILE :dsdl -opt >;$<TARGET_FILE :dsdld >"
941993 -DOUTPUT_DIR=${LLVMDSDL_SELF_CONTAINED_TOOLS_DIR}
942994 -DLLVMDSDL_SOURCE_DIR=${LLVMDSDL_SOURCE_DIR}
943995 -P ${LLVMDSDL_SOURCE_DIR } /cmake/BundleSelfContainedTools.cmake
944- DEPENDS dsdlc dsdl-opt
996+ DEPENDS ${LLVMDSDL_INSTALLABLE_TOOLS}
945997 USES_TERMINAL
946998 VERBATIM
947999 COMMENT
0 commit comments