[Openmp-commits] [openmp] [OpenMP] Allow building shared and static libomp together (PR #208721)

Mark Zhuang via Openmp-commits openmp-commits at lists.llvm.org
Fri Jul 10 06:21:15 PDT 2026


https://github.com/zqb-all created https://github.com/llvm/llvm-project/pull/208721

Add LIBOMP_ENABLE_STATIC so the shared and static libraries can be enabled at the same time. When both are on, one build makes libomp.so and libomp.a

Assisted-by: claude

>From 5afddba9b4638d59d29116f7dcf49cdcd03c6051 Mon Sep 17 00:00:00 2001
From: Mark Zhuang <mark.zhuang at spacemit.com>
Date: Fri, 10 Jul 2026 00:05:06 +0800
Subject: [PATCH] [OpenMP] Allow building shared and static libomp together

Add LIBOMP_ENABLE_STATIC so the shared and static libraries can be
enabled at the same time. When both are on, one build makes libomp.so
and libomp.a

Assisted-by: claude
---
 openmp/runtime/CMakeLists.txt         | 12 +++--
 openmp/runtime/src/CMakeLists.txt     | 66 +++++++++++++++++++++++++++
 openmp/runtime/src/kmp_config.h.cmake |  4 ++
 3 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/openmp/runtime/CMakeLists.txt b/openmp/runtime/CMakeLists.txt
index c0f5b5a4b1596..4b1edfa24edeb 100644
--- a/openmp/runtime/CMakeLists.txt
+++ b/openmp/runtime/CMakeLists.txt
@@ -332,16 +332,22 @@ endif()
 set(LIBOMP_USE_CANCEL_THREADS "${LIBOMP_HAVE_PTHREAD_CANCEL}" CACHE BOOL
   "Enable thread cancellation via pthread_cancel?")
 
-# Shared library can be switched to a static library
+# Shared and static libraries can be enabled at the same time.
 set(LIBOMP_ENABLE_SHARED TRUE CACHE BOOL
-  "Shared library instead of static library?")
+  "Build the OpenMP runtime as a shared library.")
+set(LIBOMP_ENABLE_STATIC FALSE CACHE BOOL
+  "Build the OpenMP runtime as a static library.")
 
 if(WASM)
   libomp_warning_say("The WebAssembly build currently only supports static libraries; forcing LIBOMP_ENABLE_SHARED to false")
   set(LIBOMP_ENABLE_SHARED FALSE)
 endif()
 
-if(WIN32 AND NOT LIBOMP_ENABLE_SHARED)
+if(NOT LIBOMP_ENABLE_SHARED AND NOT LIBOMP_ENABLE_STATIC)
+  set(LIBOMP_ENABLE_STATIC TRUE)
+endif()
+
+if(WIN32 AND LIBOMP_ENABLE_STATIC)
   libomp_error_say("Static libraries requested but not available on Windows")
 endif()
 
diff --git a/openmp/runtime/src/CMakeLists.txt b/openmp/runtime/src/CMakeLists.txt
index 42729674481e5..ba575d89a3d65 100644
--- a/openmp/runtime/src/CMakeLists.txt
+++ b/openmp/runtime/src/CMakeLists.txt
@@ -171,6 +171,20 @@ add_library(obj.omp OBJECT ${LIBOMP_SOURCE_FILES})
 set_property(TARGET obj.omp PROPERTY FOLDER "OpenMP/Libraries")
 set_property(TARGET obj.omp PROPERTY POSITION_INDEPENDENT_CODE ON)
 
+if(LIBOMP_ENABLE_SHARED AND LIBOMP_ENABLE_STATIC)
+  set(LIBOMP_BUILD_SHARED_AND_STATIC TRUE)
+else()
+  set(LIBOMP_BUILD_SHARED_AND_STATIC FALSE)
+endif()
+
+if(LIBOMP_BUILD_SHARED_AND_STATIC)
+  add_library(obj.omp.static OBJECT ${LIBOMP_SOURCE_FILES})
+  set_property(TARGET obj.omp.static PROPERTY FOLDER "OpenMP/Libraries")
+  set_property(TARGET obj.omp.static PROPERTY POSITION_INDEPENDENT_CODE ON)
+  target_compile_definitions(obj.omp.static PRIVATE KMP_DYNAMIC_LIB=0)
+  set(LIBOMP_STATIC_LIB_FILE ${LIBOMP_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
+endif()
+
 libomp_get_ldflags(LIBOMP_CONFIGURED_LDFLAGS)
 libomp_get_libflags(LIBOMP_CONFIGURED_LIBFLAGS)
 
@@ -181,12 +195,24 @@ if(NOT OPENMP_ENABLE_LIBOMP_PROFILING)
   set_property(TARGET omp PROPERTY FOLDER "OpenMP/Libraries")
   # Linking command will include libraries in LIBOMP_CONFIGURED_LIBFLAGS
   target_link_libraries(omp ${LIBOMP_CONFIGURED_LIBFLAGS} ${LIBOMP_DL_LIBS})
+  if(LIBOMP_BUILD_SHARED_AND_STATIC)
+    add_library(omp_static STATIC $<TARGET_OBJECTS:obj.omp.static>)
+    set_property(TARGET omp_static PROPERTY FOLDER "OpenMP/Libraries")
+    target_link_libraries(omp_static ${LIBOMP_CONFIGURED_LIBFLAGS} ${LIBOMP_DL_LIBS})
+  endif()
 else()
   add_llvm_library(omp ${LIBOMP_LIBRARY_KIND} $<TARGET_OBJECTS:obj.omp> PARTIAL_SOURCES_INTENDED
     LINK_LIBS ${LIBOMP_CONFIGURED_LIBFLAGS} ${LIBOMP_DL_LIBS}
     LINK_COMPONENTS Support
     BUILDTREE_ONLY
     )
+  if(LIBOMP_BUILD_SHARED_AND_STATIC)
+    add_llvm_library(omp_static STATIC $<TARGET_OBJECTS:obj.omp.static> PARTIAL_SOURCES_INTENDED
+      LINK_LIBS ${LIBOMP_CONFIGURED_LIBFLAGS} ${LIBOMP_DL_LIBS}
+      LINK_COMPONENTS Support
+      BUILDTREE_ONLY
+      )
+  endif()
   # libomp must be a C++ library such that it can link libLLVMSupport
   set(LIBOMP_LINKER_LANGUAGE CXX)
 endif()
@@ -205,6 +231,12 @@ if(LIBOMP_USE_HWLOC)
     INTERFACE
     "$<BUILD_INTERFACE:${LIBOMP_HWLOC_INCLUDE_DIR}>"
     "$<INSTALL_INTERFACE:${LIBOMP_HWLOC_INCLUDE_DIR}>")
+  if(LIBOMP_BUILD_SHARED_AND_STATIC)
+    target_include_directories(obj.omp.static
+      PRIVATE
+      "$<BUILD_INTERFACE:${LIBOMP_HWLOC_INCLUDE_DIR}>"
+      "$<INSTALL_INTERFACE:${LIBOMP_HWLOC_INCLUDE_DIR}>")
+  endif()
 endif()
 
 if(OPENMP_MSVC_NAME_SCHEME)
@@ -242,6 +274,12 @@ else()
     LINK_FLAGS "${LIBOMP_CONFIGURED_LDFLAGS}"
     LINKER_LANGUAGE ${LIBOMP_LINKER_LANGUAGE}
   )
+  if(LIBOMP_BUILD_SHARED_AND_STATIC)
+    set_target_properties(omp_static PROPERTIES
+      PREFIX "" SUFFIX "" OUTPUT_NAME "${LIBOMP_STATIC_LIB_FILE}"
+      LINKER_LANGUAGE ${LIBOMP_LINKER_LANGUAGE}
+    )
+  endif()
 endif()
 
 # Get the library's location within the build tree for the unit tester
@@ -290,6 +328,15 @@ if(NOT WIN32)
         WORKING_DIRECTORY ${LIBOMP_LIBRARY_DIR}
       )
     endif()
+    if(LIBOMP_BUILD_SHARED_AND_STATIC)
+      add_custom_command(TARGET omp_static POST_BUILD
+        COMMAND ${CMAKE_COMMAND} -E create_symlink ${LIBOMP_STATIC_LIB_FILE}
+          libiomp5${CMAKE_STATIC_LIBRARY_SUFFIX}
+        COMMAND ${CMAKE_COMMAND} -E create_symlink ${LIBOMP_STATIC_LIB_FILE}
+          libgomp${CMAKE_STATIC_LIBRARY_SUFFIX}
+        WORKING_DIRECTORY ${LIBOMP_LIBRARY_DIR}
+      )
+    endif()
   endif()
 endif()
 
@@ -304,6 +351,9 @@ set(LIBOMPTARGET_OPENMP_HOST_RTL_FOLDER "${LIBOMP_LIBRARY_DIR}" CACHE STRING
 add_custom_target(libomp-needed-headers DEPENDS kmp_i18n_id.inc kmp_i18n_default.inc)
 set_target_properties(libomp-needed-headers PROPERTIES FOLDER "OpenMP/Sourcegenning")
 add_dependencies(obj.omp libomp-needed-headers)
+if(LIBOMP_BUILD_SHARED_AND_STATIC)
+  add_dependencies(obj.omp.static libomp-needed-headers)
+endif()
 
 # Windows specific build rules
 if(WIN32)
@@ -409,6 +459,12 @@ set(export_to_llvmexports)
 get_target_export_arg(omp LLVM export_to_llvmexports)
 set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS omp)
 
+set(export_to_static_llvmexports)
+if(LIBOMP_BUILD_SHARED_AND_STATIC)
+  get_target_export_arg(omp_static LLVM export_to_static_llvmexports)
+  set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS omp_static)
+endif()
+
 # Install rules
 # We want to install libomp in ${DESTDIR}/${CMAKE_INSTALL_FULL_LIBDIR}
 # We want to install headers in ${DESTDIR}/${CMAKE_INSTALL_FULL_INCLUDEDIR}
@@ -430,6 +486,9 @@ if(WIN32)
 else()
 
   install(TARGETS omp ${export_to_llvmexports} ${LIBOMP_INSTALL_KIND} DESTINATION "${OPENMP_INSTALL_LIBDIR}" COMPONENT openmp)
+  if(LIBOMP_BUILD_SHARED_AND_STATIC)
+    install(TARGETS omp_static ${export_to_static_llvmexports} ARCHIVE DESTINATION "${OPENMP_INSTALL_LIBDIR}" COMPONENT openmp)
+  endif()
 
   if(LIBOMP_INSTALL_ALIASES)
     # Create aliases (symlinks) of the library for backwards compatibility
@@ -451,6 +510,13 @@ else()
         \"${VERSIONED_LIBGOMP_NAME}\" WORKING_DIRECTORY
         \"\$ENV{DESTDIR}${outdir}\")" COMPONENT openmp)
     endif()
+    if(LIBOMP_BUILD_SHARED_AND_STATIC)
+      foreach(alias IN LISTS LIBOMP_ALIASES)
+        install(CODE "execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E create_symlink \"${LIBOMP_STATIC_LIB_FILE}\"
+          \"${alias}${CMAKE_STATIC_LIBRARY_SUFFIX}\" WORKING_DIRECTORY
+          \"\$ENV{DESTDIR}${outdir}\")" COMPONENT openmp)
+      endforeach()
+    endif()
   endif()
 endif()
 install(
diff --git a/openmp/runtime/src/kmp_config.h.cmake b/openmp/runtime/src/kmp_config.h.cmake
index c5e8cfa5154e9..477ff7c0e39d9 100644
--- a/openmp/runtime/src/kmp_config.h.cmake
+++ b/openmp/runtime/src/kmp_config.h.cmake
@@ -65,7 +65,11 @@
 #cmakedefine01 LIBOMP_USE_HWLOC
 #define KMP_USE_HWLOC LIBOMP_USE_HWLOC
 #cmakedefine01 LIBOMP_ENABLE_SHARED
+// Shared and static libraries need different code, so KMP_DYNAMIC_LIB may be
+// set per object library on the command line. Only set it here if not set yet.
+#ifndef KMP_DYNAMIC_LIB
 #define KMP_DYNAMIC_LIB LIBOMP_ENABLE_SHARED
+#endif
 #define KMP_ARCH_STR "@LIBOMP_LEGAL_ARCH@"
 #define KMP_LIBRARY_FILE "@LIBOMP_LIB_FILE@"
 #define KMP_VERSION_MAJOR @LIBOMP_VERSION_MAJOR@



More information about the Openmp-commits mailing list