Combing them wasn't my idea but it definitely simplifies the rest of the system. I think it's meant to work out of the box, but on llvm 6 release at least it needs some handholding. There's a description of the method and the bash script I'm running below.
Your crt* workaround looks sound. It's a bit sad to create files that lld wants but doesn't need. I'm doing the same.
I'll look at miniz and netbsd-curses, thanks. Certainly worth a try.
Cheers!
Jon
libc++ has working support for bundling a libcxxabi.a into the shared/static library. That worked for me building the libraries separately or simultaneously.
libcxxabi has cmake options that suggests it can incorporate libunwind. That didn't work for me, either building separately or together.
Strategy is therefore:
- put all the source directories next to each other
- compile libunwind.a
- combine libcxxabi.a
- merge into an archive (misleadingly) called libcxxabi.a
- point libc++ to that external archive and let cmake merge it with libc++
The cmake uses a python script to merge static archives which also does a degree of looking around the filesystem for them. Merging archives robustly is remarkably tedious if the objects could have the same name. gnu ar and llvm-ar both know how to do this safely via mri scripts.
buildcxxlib() {
CC=$1
CFLAGS=$2
CXX=$3
CXXFLAGS=$4
INSTALL=$5
BUILD=$6
COMPILER_RT=$7
COMMON_FLAGS="-DLLVM_PATH=$SRC/llvm
-DLLVM_MAIN_SRC_DIR=$SRC/llvm
-DCMAKE_ASM_COMPILER=$CC
-DCMAKE_C_COMPILER=$CC
-DCMAKE_C_FLAGS=$CFLAGS \
-DCMAKE_CXX_COMPILER=$CXX \
-DCMAKE_CXX_FLAGS=$CXXFLAGS \
-DCMAKE_BUILD_TYPE=Release"
echo "make libunwind"
mkdir -p "$BUILD/libunwind" && cd "$BUILD/libunwind"
cmake $COMMON_FLAGS \
-DCMAKE_INSTALL_PREFIX=$INSTALL \
-DLIBUNWIND_USE_COMPILER_RT=$COMPILER_RT \
-DLIBUNWIND_ENABLE_STATIC=ON \
-DLIBUNWIND_ENABLE_SHARED=OFF \
$SRC/llvm/projects/libunwind
make -j `nproc` install
cd ../..
echo "make libcxxabi"
mkdir -p "$BUILD/libcxxabi" && cd "$BUILD/libcxxabi"
# -DLIBCXXABI_ENABLE_STATIC_UNWINDER doesnt seem to be implemented
cmake $COMMON_FLAGS \
-DCMAKE_INSTALL_PREFIX=$INSTALL \
-DLIBCXXABI_USE_COMPILER_RT=$COMPILER_RT \
-DLIBCXXABI_USE_LLVM_UNWINDER=ON \
-DLIBCXXABI_ENABLE_STATIC=ON \
-DLIBCXXABI_ENABLE_SHARED=OFF \
$SRC/llvm/projects/libcxxabi
make -j `nproc` install
cd ../..
echo "Combine libunwind and libcxxabi into a single static library"
mkdir -p $INSTALL/tmp
echo "create $INSTALL/lib/libunwindc++abi.a
addlib $INSTALL/lib/libunwind.a
addlib $INSTALL/lib/libc++abi.a
save
end" | llvm-ar -M
rm $INSTALL/lib/libunwind.a $INSTALL/lib/libc++abi.a
mv $INSTALL/lib/libunwindc++abi.a $INSTALL/lib/libc++abi.a
rm -rf $INSTALL/tmp
echo "make libcxx"
# Setting rpath here could be useful for letting libc++ find libc
mkdir -p "$BUILD/libcxx" && cd "$BUILD/libcxx"
cmake $COMMON_FLAGS \
-DCMAKE_INSTALL_PREFIX=$INSTALL \
-DLIBCXX_USE_COMPILER_RT=$COMPILER_RT \
-DLLVM_TARGETS_TO_BUILD="$TARGETS" \
-DLIBCXX_ENABLE_STATIC=ON \
-DLIBCXX_ENABLE_SHARED=ON \
-DLIBCXX_CXX_ABI="libcxxabi" \
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=$SRC/llvm/projects/libcxxabi/include \
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF \
-DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON \
-DLIBCXX_CXX_ABI_LIBRARY_PATH=$BUILD/install/lib \
-DCMAKE_INSTALL_RPATH="$BUILD/install/lib" \
$SRC/llvm/projects/libcxx
make -j `nproc` install
cd ../..
rm $INSTALL/lib/libc++abi.a
}