[OpenMP] How to properly solve Error #15 and link single OpenMP runtime on Winodows, using CMake (original) (raw)

Hi everyone, I am encountering problems while compiling my project using clang-cl and linking to the OpenMP runtime on Windows 11, using CMake.

To give some context, I have a CMake project with multiple targets.
The main target is a (shared) library linked against different executables for testing and benchmarking purposes.
The project is stable using the Visual Studio 17 2022 generator and the MSVC compiler, so now I am adding support for clang-cl using the Ninja generator.

I installed the LLVM Clang using the installer found on the GitHub page. Both the library and test targets compile correctly, but when running the compiler I obtain the following warning message printed to the console

OMP: Error #15: Initializing libomp.dll, but found libiomp5md.dll already initialized.
OMP: Hint This means that multiple copies of the OpenMP runtime have been linked into the program.
That is dangerous, since it can degrade performance or cause incorrect results. The best thing
to do is to ensure that only a single OpenMP runtime is linked into the process, e.g. by avoiding
static linking of the OpenMP runtime in any library. As an unsafe, unsupported, undocumented
workaround you can set the environment variable KMP_DUPLICATE_LIB_OK=TRUE to allow the program to
continue to execute, but that may cause crashes or silently produce incorrect results.
For more information, please see http://openmp.llvm.org/

I looked online and no one provides a solution different from activating the environment variable. I would like to avoid this solution since it is clearly not desirable.

From my understanding, the conflict is generated by the usage of two different OpenMP runtimes:

  1. libomp.dll which is the one provided by the LLVM distribution, which I explicitly link using CMake
  2. libiomp5md.dll which is (one of) the runtime found in the Visual Studio installation directory

I do not explicitly link to libiomp5md.dll, so why is the compiler looking for it? Does anyone know how to solve this problem properly?

I will add some snippets from my CMake project

include(cmake/setupVc.cmake) # find and run vcvars batch file

# ...

# Add OpenMP compilation flags  
add_compile_options($<$<BOOL:ENABLE_OPENMP>:-Xclang>)
add_compile_options($<$<BOOL:ENABLE_OPENMP>:-fopenmp>)

# Prepare OpenMP paths
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  cmake_path(GET CMAKE_CXX_COMPILER PARENT_PATH LLVM_BIN)
  cmake_path(GET LLVM_BIN PARENT_PATH LLVM_DIR)
  set(OpenMP_LIB "${LLVM_DIR}/lib/libomp.lib")
  set(OpenMP_BIN "${LLVM_DIR}/bin/libomp.dll")
  copy_dll(${OpenMP_BIN}) # copy the DLL into the bin directory (optional)
endif()

# Link library target to OpenMP
target_link_libraries(MyLibTarget PRIVATE ${OpenMP_LIB})

Thank you in advance for your support.