Cross-compiling openmp runtime -- CMake bug?

Hi,

I am interested in cross-compiling the openmp runtime. This is just for the OpenMP that supports the CPU only (no target, no accelerator). I have managed to do this for the other runtimes and the builtins, but not for openmp.

I am following the recipes in the Fuschia*.cmake here:

as well as the recent tutorial

by @petrhosek.

I am posting my MyCache.cmake file here:

Here is how I invoke it on my x86 host:

BUILD_DIR=build_test
cmake -S llvm -B ${BUILD_DIR} -G Ninja -C MyCache.cmake \
      -D LINUX_x86_64-unknown-linux-gnu_SYSROOT=/lib/x86_64-linux-gnu \
      -D LINUX_aarch64-unknown-linux-gnu_SYSROOT=/lib/aarch64-linux-gnu \
      -D CMAKE_INSTALL_PREFIX=$HOME/llvm_test

ninja -C ${BUILD_DIR}
ninja -C ${BUILD_DIR} install

I am on an x86 host and building the runtimes for x86 and aarch64. If I go into lib/[x86_64-linux-gnu, aarch64-linux-gnu] directories, I can confirm that libc++, libc++abi.a, libunwind.a are built for their respective architecture using readelf. Similarly, for the static libraries in lib/clang/18/lib/[x86_64-linux-gnu, aarch64-linux-gnu].

I do manage to build/install a lib/[libgomp.a,libiomp5.a], but it is not located in the directory that I expect it to be installed. Additionally, the version installed appears to be aarch64 (which is the last target architecture in my list).

My current theory is that I am building openmp runtime for both x86 and aarch64 but they just get installed into the same directory and thus just end up clobbering each other.

Thanks in advanced for your thoughts and suggestions.

The build of OpenMP is “slightly” different from other runtime projects. I heard successful story of cross compiling OpenMP via standalone build by set LIBOMP_ARCH CMake variable.

We’ve been cross-compiling openmp in conda-forge for a long time (osx-arm64 from osx-64, linux-aarch64 from linux-64 and linux-ppc64le from linux-64). You can check out the “recipe” here, or the logs from the last run here.

For convenience, I’ve copied out the main cmake invocation from the log:

cmake -G Ninja \
    -DCMAKE_AR=$BUILD_PREFIX/bin/aarch64-conda-linux-gnu-ar \
    -DCMAKE_C_COMPILER_AR=$BUILD_PREFIX/bin/aarch64-conda-linux-gnu-gcc-ar \
    -DCMAKE_C_COMPILER_RANLIB=$BUILD_PREFIX/bin/aarch64-conda-linux-gnu-gcc-ranlib \
    -DCMAKE_CXX_COMPILER_AR=$BUILD_PREFIX/bin/aarch64-conda-linux-gnu-gcc-ar \
    -DCMAKE_CXX_COMPILER_RANLIB=$BUILD_PREFIX/bin/aarch64-conda-linux-gnu-gcc-ranlib \
    -DCMAKE_LINKER=$BUILD_PREFIX/bin/aarch64-conda-linux-gnu-ld \
    -DCMAKE_RANLIB=$BUILD_PREFIX/bin/aarch64-conda-linux-gnu-ranlib \
    -DCMAKE_STRIP=$BUILD_PREFIX/bin/aarch64-conda-linux-gnu-strip \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
    -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
    -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
    -DCMAKE_FIND_ROOT_PATH=$PREFIX;$BUILD_PREFIX/aarch64-conda-linux-gnu/sysroot \
    -DCMAKE_INSTALL_PREFIX=$PREFIX \
    -DCMAKE_INSTALL_LIBDIR=lib \
    -DCMAKE_PREFIX_PATH=$PREFIX \
    -DCMAKE_PROGRAM_PATH=$BUILD_PREFIX/bin;$PREFIX/bin \
    -DCMAKE_SYSTEM_NAME=Linux \
    -DCMAKE_SYSTEM_PROCESSOR=aarch64 \
    ..

The key quantities here are $PREFIX, the environment with the target architecture that we’re compiling for and $BUILD_PREFIX, the environment of the build environment (matching the x64 architecture of the agent) that we’re compiling from.

The way we’ve set up compiler binary naming (triple-ish) is not relevant, you just need to have (and point to!) the ones that can be executed on your build architecture. Also, some of CMAKE_<compiler_bin> quantities in the beginning are likely not necessary, we just inject them by default.

PS. This relies on having llvm-the-library (w/ headers) built for the right architecture in $PREFIX at build time; we also cross-compile that.

@h-vetinari Thank you kind for your build recipe. This looks like an out-of-tree recipe that is using the GCC cross-compiling toolchain to build the LLVM OpenMP library. This will definitely work.

I am particularly interested in an in-tree recipe that is using the in-tree/just-built clang compiler. The recipe I posted works with the other runtimes, but not with openmp. I wanted to post the issue first on Discourse, before I do a deep dive into the OpenMP runtime’s CMake.