Skip to content

Instantly share code, notes, and snippets.

@scivision
Last active March 9, 2026 04:11
Show Gist options
  • Select an option

  • Save scivision/33bd9e17c9520d07be0448fe61541605 to your computer and use it in GitHub Desktop.

Select an option

Save scivision/33bd9e17c9520d07be0448fe61541605 to your computer and use it in GitHub Desktop.
build script for LLVM & Flang-f18 Fortran compiler

Build LLVM Flang Fortran (and C/C++ Clang) compilers

This brief CMake script works across operating systems to build Flang-f18 and LLVM from source. It is inspired by Jeff Hammond.

cmake -B build --install-prefix=/path/to/install-llvm

Build + install LLVM Flang:

cmake --build build

by specifying the "url" variable, particular versions of LLVM can be built, for example the 22.x release:

cmake -B build \
	-Durl=https://github.com/llvm/llvm-project/archive/refs/heads/release/22.x.zip

The source download is about 300 MB. LLVM takes about a half-hour to build on a powerful laptop or workstation.

To use the compiler after install:

source clang-latest.sh

or on Windows Powershell:

. clang-latest.ps1

LLVM projects

Troubleshooting

See ulimit settings if link failures occur.

Disk usage

The installed binaries take a few gigabytes of disk space.

du -sh ~/llvm-latest  # the install prefix

3.5G

About 3.5 Gigabytes are used for the installed LLVM binaries.

The source directory can be deleted after the build / install is complete.

du -sh $TMPDIR/llvm-src

1.8G

The build directory can be deleted after the build / install is complete.

du -sh $TMPDIR/llvm-build

5.0G

#!/bin/bash -xe
# -x: verbose
# -e: exit on error
# Ninja is recommended for best build efficiency and speed
# always use the ".zip" source file
# adapted from https://github.com/jeffhammond/HPCInfo/blob/master/buildscripts/llvm-git.sh
remote="${1:-https://github.com/llvm/llvm-project/archive/refs/heads/main.zip}"
[[ -z $remote ]] && { echo "Usage: $0 [archive_url]" && exit 1; }
# use TMPDIR if not empty, else /tmp
TMPDIR=${TMPDIR:-/tmp}
llvm_src=${TMPDIR}/llvm-src
llvm_build=${TMPDIR}/llvm-build
prefix=$HOME/llvm-latest
stem=$(basename ${remote} .zip)
cmake_root=${llvm_src}/llvm-project-${stem}/llvm
llvm_projects="lld;mlir;clang;flang;openmp;pstl"
echo "LLVM projects: $llvm_projects"
echo "LLVM source: $llvm_src"
echo "LLVM build: $llvm_build"
echo "LLVM install: $prefix"
mkdir -p $prefix
mkdir -p $llvm_src
mkdir -p $llvm_build
# Git not used as it's so slow for a huge project history like LLVM.
# git clone --recursive https://github.com/llvm/llvm-project.git $llvm_src
# ~300 MB
archive=${TMPDIR}/llvm_main.zip
# Download/update the source
[[ -f $archive ]] || curl --location --output ${archive} ${remote}
[[ -f ${cmake_root}/CMakeLists.txt ]] || unzip -d $llvm_src $archive
[[ $(which ninja) ]] && CMAKE_GENERATOR="Ninja" || CMAKE_GENERATOR="Unix Makefiles"
case "$(uname -m)" in
arm64|aarch64)
llvm_arch=AArch64
;;
*)
llvm_arch=X86
;;
esac
# helpful system parameters
case "$OSTYPE" in
darwin*)
macos_sysroot=-DDEFAULT_SYSROOT="$(xcrun --show-sdk-path)"
;;
*)
llvm_linker=-DLLVM_USE_LINKER=gold
;;
esac\
# lldb busted on MacOS
# libcxx requires libcxxabi
cmake \
-G"$CMAKE_GENERATOR" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_TARGETS_TO_BUILD=$llvm_arch \
-DLLVM_ENABLE_RUNTIMES="libcxxabi;libcxx;libunwind" \
-DLLVM_ENABLE_PROJECTS=${llvm_projects} \
$macos_sysroot \
$llvm_linker \
--install-prefix=$prefix \
-S${cmake_root} \
-B${llvm_build}
cmake --build ${llvm_build}
cmake --install ${llvm_build}
r=$HOME/llvm-latest
b=${r}/bin
export CC=${b}/clang CXX=${b}/clang++ FC=${b}/flang
# flags below not generally needed
#export LDFLAGS="-L${r}/lib"
#export CPPFLAGS="-I${r}/include"
#case "$OSTYPE" in
#darwin*)
# avoid missing -lSystem
#export LIBRARY_PATH="/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib"
# avoid missing libc++.1.dylib
#export DYLD_FALLBACK_LIBRARY_PATH=${r}/lib
#;;
#esac
$FC --version
cmake_minimum_required(VERSION 3.25)
project(build_flang_f18_external LANGUAGES NONE)
include(ExternalProject)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
message(FATAL_ERROR "Please tell install location with 'cmake --install-prefix'")
endif()
# Mirrors build-flang-f18.sh using CMake + ExternalProject.
if(NOT url)
set(url "https://github.com/llvm/llvm-project/archive/refs/heads/main.zip")
endif()
if(NOT projects)
# LLVM 23 projects
# bolt;clang;clang-tools-extra;cross-project-tests;lld;lldb;mlir;polly;flang;libc;compiler-rt
set(projects lld mlir clang flang)
endif()
if(NOT runtimes)
set(runtimes libc libcxxabi libcxx libunwind openmp flang-rt)
endif()
set(build_type Release)
# https://llvm.org/docs/HowToBuildOnARM.html
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _proc)
if(_proc MATCHES "^(arm64|aarch64)$")
set(target AArch64)
else()
set(target X86)
endif()
set(cmake_args
-DCMAKE_BUILD_TYPE=${build_type}
-DLLVM_TARGETS_TO_BUILD:STRING=${target}
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
)
set(cache_args
-DLLVM_ENABLE_PROJECTS:STRING=${projects}
-DLLVM_ENABLE_RUNTIMES:STRING=${runtimes}
)
if(APPLE)
execute_process(
COMMAND xcrun --show-sdk-path
OUTPUT_VARIABLE _macos_sdk_path
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE _ret
)
if(_ret EQUAL 0)
list(APPEND cmake_args "-DDEFAULT_SYSROOT:PATH=${_macos_sdk_path}")
endif()
endif()
if(LINUX)
list(APPEND cmake_args "-DLLVM_USE_LINKER=gold")
endif()
message(STATUS "LLVM CMake args: ${cmake_args}")
ExternalProject_Add(llvm_flang
URL ${url}
SOURCE_SUBDIR llvm
CMAKE_ARGS ${cmake_args}
CMAKE_CACHE_ARGS ${cache_args}
UPDATE_DISCONNECTED TRUE
USES_TERMINAL_DOWNLOAD TRUE
USES_TERMINAL_CONFIGURE TRUE
USES_TERMINAL_BUILD TRUE
USES_TERMINAL_INSTALL TRUE
)
file(GENERATE OUTPUT .gitignore CONTENT "*")
@mathomp4
Copy link

mathomp4 commented May 6, 2024

Update that the script might need. When I tried running this I got:

[6692/6762] Linking CXX shared library lib/libclang-cpp.so.19.0git
FAILED: lib/libclang-cpp.so.19.0git
...
/usr/bin/ld.gold: internal error in open, at descriptors.cc:99
collect2: error: ld returned 1 exit status

when it tried to link together what seems to be a crazy number of files. If I got my awk right, somewhere over 1300.

Searching internet seems to show that this could be a ulimit issue and on my system:

@$ ulimit -n
1024

And, well, that is less than 1300!

So I then ran:

ulimit -n 65536

and I got past it.

@scivision
Copy link
Author

Interesting. A linux system I used also had 1024 and macOS has 256. I will note it in the Readme.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment