@@ -404,7 +404,7 @@ endfunction(set_windows_version_resource_properties)
404404# )
405405function (llvm_add_library name )
406406 cmake_parse_arguments (ARG
407- "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB"
407+ "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB;ENABLE_PLUGINS "
408408 "OUTPUT_NAME;PLUGIN_TOOL;ENTITLEMENTS;BUNDLE_PATH"
409409 "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
410410 ${ARGN} )
@@ -418,6 +418,9 @@ function(llvm_add_library name)
418418 else ()
419419 llvm_process_sources(ALL_FILES ${ARG_UNPARSED_ARGUMENTS} ${ARG_ADDITIONAL_HEADERS} )
420420 endif ()
421+ if (ARG_ENABLE_PLUGINS)
422+ set_property (GLOBAL APPEND PROPERTY LLVM_PLUGIN_TARGETS ${name} )
423+ endif ()
421424
422425 if (ARG_MODULE)
423426 if (ARG_SHARED OR ARG_STATIC)
@@ -745,7 +748,7 @@ endmacro(add_llvm_library name)
745748
746749macro (add_llvm_executable name )
747750 cmake_parse_arguments (ARG
748- "DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS"
751+ "DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS;ENABLE_PLUGINS "
749752 "ENTITLEMENTS;BUNDLE_PATH"
750753 "DEPENDS"
751754 ${ARGN} )
@@ -832,10 +835,78 @@ macro(add_llvm_executable name)
832835 # API for all shared libaries loaded by this executable.
833836 target_link_libraries (${name} PRIVATE ${LLVM_PTHREAD_LIB} )
834837 endif ()
838+ if (ARG_ENABLE_PLUGINS)
839+ set_property (GLOBAL APPEND PROPERTY LLVM_PLUGIN_TARGETS ${name} )
840+ endif ()
835841
836842 llvm_codesign(${name} ENTITLEMENTS ${ARG_ENTITLEMENTS} BUNDLE_PATH ${ARG_BUNDLE_PATH} )
837843endmacro (add_llvm_executable name )
838844
845+ # add_llvm_pass_plugin(name)
846+ # Add ${name} as an llvm plugin.
847+ # If option LLVM_${name_upper}_LINK_INTO_TOOLS is set to ON, the plugin is registered statically.
848+ # Otherwise a pluggable shared library is registered.
849+ function (add_llvm_pass_plugin name )
850+
851+ string (TOUPPER ${name} name_upper)
852+
853+ option (LLVM_${name_upper} _LINK_INTO_TOOLS "Statically link ${name} into tools (if available)" OFF )
854+
855+ # process_llvm_pass_plugins takes care of the actual linking, just create an
856+ # object library as of now
857+ add_llvm_library(${name} OBJECT ${ARGN} )
858+
859+ if (LLVM_${name_upper} _LINK_INTO_TOOLS)
860+ target_compile_definitions (${name} PRIVATE LLVM_${name_upper} _LINK_INTO_TOOLS)
861+ set_property (TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS LLVM_LINK_INTO_TOOLS)
862+ if (TARGET intrinsics_gen)
863+ add_dependencies (obj.${name} intrinsics_gen)
864+ endif ()
865+ endif ()
866+
867+ message (STATUS "Registering ${name} as a pass plugin (static build: ${LLVM_${name_upper} _LINK_INTO_TOOLS})" )
868+ if (LLVM_${name_upper} _LINK_INTO_TOOLS)
869+ set_property (GLOBAL APPEND PROPERTY LLVM_COMPILE_EXTENSIONS ${name} )
870+ endif ()
871+ endfunction (add_llvm_pass_plugin)
872+
873+ # Generate X Macro file for extension handling. It provides a
874+ # HANDLE_EXTENSION(extension_namespace, ExtensionProject) call for each extension
875+ # allowing client code to define HANDLE_EXTENSION to have a specific code be run for
876+ # each extension.
877+ #
878+ # Also correctly set lib dependencies between plugins and tools.
879+ function (process_llvm_pass_plugins)
880+ get_property (LLVM_EXTENSIONS GLOBAL PROPERTY LLVM_COMPILE_EXTENSIONS)
881+ file (WRITE "${CMAKE_BINARY_DIR} /include/llvm/Support/Extension.def.tmp" "//extension handlers\n " )
882+ foreach (llvm_extension ${LLVM_EXTENSIONS} )
883+ string (TOLOWER ${llvm_extension} llvm_extension_lower)
884+
885+ string (TOUPPER ${llvm_extension} llvm_extension_upper)
886+ string (SUBSTRING ${llvm_extension_upper} 0 1 llvm_extension_upper_first)
887+ string (SUBSTRING ${llvm_extension_lower} 1 -1 llvm_extension_lower_tail)
888+ string (CONCAT llvm_extension_project ${llvm_extension_upper_first} ${llvm_extension_lower_tail} )
889+
890+ if (LLVM_${llvm_extension_upper} _LINK_INTO_TOOLS)
891+ file (APPEND "${CMAKE_BINARY_DIR} /include/llvm/Support/Extension.def.tmp" "HANDLE_EXTENSION(${llvm_extension_project} )\n " )
892+
893+ get_property (llvm_plugin_targets GLOBAL PROPERTY LLVM_PLUGIN_TARGETS)
894+ foreach (llvm_plugin_target ${llvm_plugin_targets} )
895+ set_property (TARGET ${llvm_plugin_target} APPEND PROPERTY LINK_LIBRARIES ${llvm_extension} )
896+ set_property (TARGET ${llvm_plugin_target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${llvm_extension} )
897+ endforeach ()
898+ else ()
899+ add_llvm_library(${llvm_extension_lower} MODULE obj.${llvm_extension_lower} )
900+ endif ()
901+
902+ endforeach ()
903+ file (APPEND "${CMAKE_BINARY_DIR} /include/llvm/Support/Extension.def.tmp" "#undef HANDLE_EXTENSION\n " )
904+
905+ # only replace if there's an actual change
906+ execute_process (COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_BINARY_DIR} /include/llvm/Support/Extension.def.tmp" "${CMAKE_BINARY_DIR} /include/llvm/Support/Extension.def" )
907+ file (REMOVE "${CMAKE_BINARY_DIR} /include/llvm/Support/Extension.def.tmp" )
908+ endfunction ()
909+
839910function (export_executable_symbols target )
840911 if (LLVM_EXPORTED_SYMBOL_FILE)
841912 # The symbol file should contain the symbols we want the executable to
0 commit comments