Duplicate symbols when linking libwebrtc.a on Android - c++

Building WebRTC directly is somewhat painful (& rather time consuming so not ideal in paid for CI environments) so I've opted to use some excellent precompiled static libraries released on GitHub to speed things up. This has worked perfectly for all platforms I'm targetting (Windows, MacOS, iOS, Apple TVOS, linux...) except for Android.
When linking the binary on Android I encounter several duplicate symbol errors related to the std libary:
ld: error: duplicate symbol: std::logic_error::logic_error(char const*)
>>> defined at stdexcept_default.ipp:24 (../../../../../_source/android/webrtc/src/buildtools/third_party/libc++/trunk/src/support/runtime/stdexcept_default.ipp:24)
>>> stdexcept.o:(std::logic_error::logic_error(char const*)) in archive /root/webrtc/lib/armeabi-v7a/libwebrtc.a
>>> defined at stdexcept_default.ipp:24 (/buildbot/src/android/ndk-release-r23/toolchain/llvm-project/libcxx/src/support/runtime/stdexcept_default.ipp:24)
>>> stdexcept.o:(.text._ZNSt11logic_errorC2EPKc+0x1) in archive /app/android-sdk-linux/ndk/23.1.7779620/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_static.a
...
ld: error: duplicate symbol: std::runtime_error::runtime_error(char const*)
>>> defined at stdexcept_default.ipp:35 (../../../../../_source/android/webrtc/src/buildtools/third_party/libc++/trunk/src/support/runtime/stdexcept_default.ipp:35)
>>> stdexcept.o:(std::runtime_error::runtime_error(char const*)) in archive /root/webrtc/lib/armeabi-v7a/libwebrtc.a
>>> defined at stdexcept_default.ipp:35 (/buildbot/src/android/ndk-release-r23/toolchain/llvm-project/libcxx/src/support/runtime/stdexcept_default.ipp:35)
>>> stdexcept.o:(.text._ZNSt13runtime_errorC2EPKc+0x1) in archive /app/android-sdk-linux/ndk/23.1.7779620/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_static.a
It appears that libwebrtc.a for Android includes some libc++ object files and I'm not entirely sure how to successfully link with this library here.
This might be coming down to the libwebrtc.a being compiled with Google's own patched libc++ (Based on what I've read online I believe Google contributes patches to upstream libc++ but they don't wait for the patches to go in - rather they use their fully patched version of libc++ for building WebRTC, Chrome, etc).
When compiling for Linux I actually use the exact versions of clang & libc++ that were downloaded & used in building the static library & I suspect I might need to be doing something similar here - I'm just not entirely sure how given the need to use the Android CMake toolchain.
I've put together a minimal example project on GitHub with Dockerfile that can be used to easily reproduce the above issue.
Does anyone have an idea how I can successfully link the library on Android?
For completeness the source files of interest are:
CMakeLists.txt
cmake_minimum_required(VERSION 3.23)
project(AndroidWebRTC)
set(CMAKE_CXX_STANDARD 17)
add_executable(AndroidWebRTC src/main.cpp)
target_link_libraries(AndroidWebRTC PRIVATE ${WEBRTC_LIBRARY})
add_compile_definitions(WEBRTC_POSIX WEBRTC_ANDROID WEBRTC_LINUX)
include_directories(
${WEBRTC_INCLUDE_DIR}
${WEBRTC_INCLUDE_DIR}/third_party/abseil-cpp
${WEBRTC_INCLUDE_DIR}/third_party/boringssl/src/include
${WEBRTC_INCLUDE_DIR}/third_party/libyuv/include
${WEBRTC_INCLUDE_DIR}/third_party/zlib
)
Dockerfile
# I explicitly specify an amd64 platform as I often build on Apple Silicon
# machines where the default of arm64 breaks things. I believe the alternative
# (and possibly better option) is to use NDK 24 and above, see:
# https://stackoverflow.com/a/69541958
FROM --platform=linux/amd64 ubuntu:20.04 AS build
ENV ANDROID_SDK_ROOT /app/android-sdk-linux
WORKDIR /app
# Install dependencies to build the project
# include apt-get --no-install-recommends
RUN apt-get update && \
apt-get -y upgrade && \
apt-get --no-install-recommends -y install tzdata && \
echo 'Europe/London' > /etc/timezone && \
dpkg-reconfigure -f noninteractive tzdata
RUN apt-get --no-install-recommends -y install git lsb-release python rsync \
emacs wget build-essential sudo pkg-config clang unzip openjdk-8-jdk ant \
android-sdk-platform-tools-common libncurses5 curl
RUN mkdir ${ANDROID_SDK_ROOT}
# ------------------------------------------------------
# --- Android SDK
RUN wget https://dl.google.com/android/repository/commandlinetools-linux-7583922_latest.zip && \
unzip commandlinetools-linux-7583922_latest.zip && \
mkdir ${ANDROID_SDK_ROOT}/cmdline-tools/ &&\
mv cmdline-tools ${ANDROID_SDK_ROOT}/cmdline-tools/latest && \
rm commandlinetools-linux-7583922_latest.zip
ENV PATH ${PATH}:${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin
RUN yes | sdkmanager --licenses
RUN touch /root/.android/repositories.cfg
# Platform tools
RUN yes | sdkmanager "platform-tools"
RUN yes | sdkmanager --update --channel=0
# Keep all sections in descending order!
RUN yes | sdkmanager \
"platforms;android-30" \
"build-tools;31.0.0" \
"ndk;23.1.7779620" \
"extras;android;m2repository" \
"extras;google;m2repository" \
"extras;google;google_play_services" \
"add-ons;addon-google_apis-google-24"
ENV ANDROID_HOME ${ANDROID_SDK_ROOT}
ENV ANDROID_NDK_HOME=${ANDROID_SDK_ROOT}/ndk/23.1.7779620
ENV PATH ${PATH}:${ANDROID_NDK_HOME}:${ANDROID_HOME}/build-tools/31.0.0/
# Get CMake
COPY scripts/get_cmake.sh scripts/get_cmake.sh
RUN ./scripts/get_cmake.sh "3.25.1" linux /root
ENV PATH "/root/cmake/bin:$PATH"
# Get WebRTC
COPY scripts/get_webrtc.sh scripts/get_webrtc.sh
RUN ./scripts/get_webrtc.sh 108.5359.5.0 android /root /root
## Copy resources
COPY src src
COPY CMakeLists.txt ./
RUN cmake -B build \
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake" \
-DANDROID_ABI=armeabi-v7a \
-DANDROID_NATIVE_API_LEVEL=16 \
-DBUILD_SHARED_LIBS=OFF \
-DWEBRTC_INCLUDE_DIR=/root/webrtc/include \
-DWEBRTC_LIBRARY=/root/webrtc/lib/armeabi-v7a/libwebrtc.a \
-DCMAKE_BUILD_TYPE=Release
RUN cmake --build build --config Release --parallel $(nproc) --target AndroidWebRTC
src/main.cpp
#include <iostream>
#include <api/create_peerconnection_factory.h>
int main() {
auto googleSessionDescription = webrtc::CreateSessionDescription(
webrtc::SdpType::kOffer, "sdp");
std::cout << "Hello, World!" << std::endl;
return 0;
}
scripts/get_webrtc.sh
#!/bin/bash
if [ $# -lt 4 ]; then
echo "$0 <webrtc_build_version> <package_name> <output_dir> <source_dir>"
exit 1
fi
WEBRTC_BUILD_VERSION=$1
PACKAGE_NAME=$2
OUTPUT_DIR=$3
SOURCE_DIR=$4
set -ex
if [ ! -e $SOURCE_DIR/webrtc.${PACKAGE_NAME}.${WEBRTC_BUILD_VERSION}.tar.gz ]; then
curl -Lo $SOURCE_DIR/webrtc.${PACKAGE_NAME}.${WEBRTC_BUILD_VERSION}.tar.gz https://github.com/shiguredo-webrtc-build/webrtc-build/releases/download/m${WEBRTC_BUILD_VERSION}/webrtc.${PACKAGE_NAME}.tar.gz
fi
pushd $OUTPUT_DIR
tar xf $SOURCE_DIR/webrtc.${PACKAGE_NAME}.${WEBRTC_BUILD_VERSION}.tar.gz
popd
scripts/get_cmake.sh
#!/bin/bash
# <platform> には Linux か Darwin を指定する
# <output_dir>/cmake に CMake が配置される
if [ $# -lt 3 ]; then
echo "$0 <cmake_version> <platform> <output_dir>"
exit 1
fi
CMAKE_VERSION=$1
PLATFORM=$2
OUTPUT_DIR=$3
set -ex
pushd $OUTPUT_DIR
curl -LO https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-${PLATFORM}-x86_64.tar.gz
tar xf cmake-${CMAKE_VERSION}-${PLATFORM}-x86_64.tar.gz
rm cmake-${CMAKE_VERSION}-${PLATFORM}-x86_64.tar.gz
rm -rf cmake
mv cmake-${CMAKE_VERSION}-${PLATFORM}-x86_64 cmake
popd

Related

How to build Opencv code in a docker file

I want to build and run a c++ opencv code using docker. Here is my dockerfile:
FROM nvidia/cuda:11.5.0-cudnn8-runtime-ubuntu20.04
FROM ubuntu
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y \
g++ git wget cmake sudo
RUN apt-get install -y \
build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev \
python3-dev python3-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev \
libcanberra-gtk-module libcanberra-gtk3-module
RUN git clone https://github.com/opencv/opencv.git && \
cd /opencv && mkdir build && cd build && \
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local .. && \
make -j"$(nproc)" && \
make install && ldconfig
The above commands makes my opencv libs, but I don't how to use it to run the actual code. I added this two lines at the end of the dockerfile (wav.cpp is the name of my cpp file that I want to run):
COPY . .
RUN g++ -o wav wav.cpp
But at the end I get this error, which obviously says it can't find the opencv headers.
wav.cpp:2:10: fatal error: opencv2/imgproc.hpp: No such file or
directory
2 | #include "opencv2/imgproc.hpp"
| ^~~~~~~~~~~~~~~~~~~~~ compilation terminated.
Now how should I resolve this header (and lib) dependency problem?
Thank you.
You didn't specify the location for the headers and which libraries should be linked by gcc. Please take a look at the manual of gcc/g++ for the flags -I and -L. Should be something like this:
RUN g++ -o wav wav.cpp -I <opencv header location> -L <opencv libs location> -lopencv_core ....
Using #emrhzc's answer I could build my code inside the dockerfile. Now my final working command is:
RUN g++ -o wav wav.cpp `pkg-config --cflags --libs opencv4`

After make install via cmake - grpc forlders is empty

I try to installing GRPC from sources.
I have Oracle Linux 7.9, GCC 10.2.1 from devtoolset-10 and cmake version 3.21.0-rc1 built from sources.
The way i used:
git clone --recurse-submodules -b v1.37.0 https://github.com/grpc/grpc
cd grpc
mkdir -p cmake/build
pushd cmake/build
cmake -DgRPC_INSTALL=ON \
-DgRPC_BUILD_TESTS=OFF \
-DCMAKE_INSTALL_PREFIX=$/usr/local/bin \
../..
make
make install
After this i see that files from /root/grpc/cmake/build$/usr/local/bin/lib/....files been created in /usr/local/....
Ok. But when i change directory to /usr/local - this directory does`t content files from make install.
What i doing wrong?
BTW, when i try to built 1.38 version of GRPS i return building error:
/root/grpc/src/core/lib/gpr/log_linux.cc: In function ‘void gpr_default_log(gpr_log_func_args*)’:
/root/grpc/src/core/lib/gpr/log_linux.cc:97:62: error: no matching function for call to ‘StrFormat(const char [22], const char*, char [64], int32_t&, long int&, const char*&, int&)’
time_buffer, now.tv_nsec, tid, display_file, args->line);
The following worked for me:
$ git clone --recurse-submodules -b v1.37.0 https://github.com/grpc/grpc
$ cmake -G Ninja -S grpc/ -B grpc-build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DgRPC_INSTALL=ON \
-DgRPC_BUILD_TESTS=OFF
$ cmake --build grpc-build --target install
The relevant differences here are that my install prefix doesn't have a stray $ in it and that I set the build type (which you must always do).
I'm on Ubuntu 20.04 LTS using CMake 3.20.5 (the latest release) and GCC 10.3.0. Please try the above commands and see if anything changes.

Could NOT find Protobuf (missing: Protobuf_PROTOC_EXECUTABLE)

When I am doing a cmake in the build directory of the project I am getting this error. Initially I got a
protobuf-config.cmake not found
error. So I gave a path of the protobuf-config.cmake file to Protobuf_DIR. Later it started to show this new error:
CMake Error at
/opt/cmake/share/cmake-3.13/Modules/FindPackageHandleStandardArgs.cmake:137
(message): Could NOT find Protobuf (missing:
Protobuf_PROTOC_EXECUTABLE)
(found suitable version "3.6.1", minimum required is "3.0.0")
I am also attaching the error log file:
https://drive.google.com/open?id=1y7BZ6lDBtxvla7r-o188xM_FjwLqwhCx
I am doing this on Ubuntu-18 with cmake version: 3.13 and protobuf version: 3.6.1
You probably don't have the Protobuf compiler and development files installed. To fix that, run this command:
sudo apt-get install protobuf-compiler libprotobuf-dev
Alternatively, if you're building Protobuf by hand, you can't build it with the build type as RelWithDebInfo because that causes issues with the library and CMake.
Installed from apt on Ubuntu 20.04, dont have permissions to /usr/include/google
To fix: sudo chmod +Xr -R /usr/include/google
Default repositories usually contain outdated protobuf version. It is best to install it manually, from sources:
git clone --progress -b v3.10.0 https://github.com/protocolbuffers/protobuf && \
( \
cd protobuf; \
mkdir build; \
cd build; \
cmake ../cmake \
-DCMAKE_BUILD_TYPE=Release \
-Dprotobuf_BUILD_SHARED_LIBS=ON \
-Dprotobuf_BUILD_TESTS=OFF; \
make -j4 install; \
) && \
rm -rf protobuf
Quickly adding here that after installing Protobuf following this answer, I had to delete the build folder in my workspace to get cmake to run without this error :)
Hy,
list your protobuf libraries with sudo apt list | grep protobuf it should tell you what it will install by default. Run protoc --version so that you see what is recognized by default now. And after that get a version from github if needed build it and install it (this should not take to long). Then run protoc --version again.

mingw-64 - Install package

I am using mingw_64 and CLion in Windows 10 to try to use a library (https://github.com/libtrading/libtrading) in a simple project, but the library requires some packages to be installed prior the use of the library. The thing is that the installing instructions are for Linux environment as follows:
# Debian
$ apt-get install pkg-config libxml2-dev libglib2.0-dev libncurses5-dev \
python-yaml libevent-dev
# Fedora
$ yum install zlib-devel libxml2-devel glib2-devel vim-common ncurses-devel \
python-yaml libevent-devel
# OSX
$ brew install libevent glib pkgconfig
$ pip install pyyaml
So, how do I install these pre-requisites in my mingw_64 and CLion in Windows 10 environment?
If you installed MinGW through MSYS2, you can use the MSYS2 pacman package manager to install additional packages:
The MSYS2 software distribution uses a port of pacman from Arch Linux to manage (install, remove and update) binary packages and also to build those packages in the first place.
Finding package
pacman -Ss <name or part of the name of the package>
Installing a package
pacman -S <name of the package>
Example:
$ pacman -Ss libxml2
mingw64/mingw-w64-x86_64-libxml2 2.9.8-1
XML parsing library, version 2 (mingw-w64)
. . .
$ pacman -S mingw64/mingw-w64-x86_64-libxml2
resolving dependencies...
looking for conflicting packages...
Total Download Size: 1.37 MiB
Total Installed Size: 11.06 MiB
:: Proceed with installation? [Y/n]
:: Retrieving packages...
:: Processing package changes...
(1/1) installing mingw-w64-x86_64-libxml2 [##################################] 100%
A shorter version of pacman is pacboy. For example, you can specify the :x suffix to install a mingw64 package:
$ pacboy -S libxml2:x
MinGW does not have any package management, so installing dependencies usually means building them yourself from source. For those self-built packages I have a Unix-like directory structure (with the usual bin, lib, include, etc. directories) apart from the MinGW installation.
Before I expand on that, please check if libTrading supports Windows at all. A quick glance over the libTrading GitHub shows no mention of Windows anywhere. That may mean that the project does not support Windows at all. But then we’re no more talking about configuring a build environment, but adding support for a whole new operating sytem to that project.
Here is the way I used
$ cat /usr/bin/install
# How to use
# install rsync
cd /
echo $1
# echo $2
URL=http://repo.msys2.org/msys/x86_64
FILE=`wget -O - -o /dev/null $URL | sed -n 's/.*href="\([^"]*\).*/\1/p' | grep -E ^$1 | egrep -v '.sig$' | sort | tail -1f`
echo $FILE
# wget -qO- $URL/$FILE | tar -I zstd -xvf - -C /
# wget -qO- $URL/$FILE | tar xJvf - -C /
if [[ $FILE == *.zst ]] # * is used for pattern matching
then
wget -qO- $URL/$FILE | tar -I zstd -xvf - -C /
elif [[ $FILE == *.xz ]]
then
wget -qO- $URL/$FILE | tar xJvf - -C /
else
echo "$FILE is not extracted"
fi
$ install whois
whois
whois-5.5.9-1-x86_64.pkg.tar.zst
.BUILDINFO
.MTREE
.PKGINFO
etc/
etc/whois.conf
usr/
usr/bin/
usr/bin/whois.exe
usr/share/
usr/share/man/
usr/share/man/man1/
usr/share/man/man1/whois.1.gz
usr/share/man/man5/
usr/share/man/man5/whois.conf.5.gz

Unknown package libcxx and libcxxabi when building Clang?

I'm trying to build Clang with libc++ from sources. And I'm trying to drop libc++ in-tree while building it out-of-tree with the other components. The recipe I use is below.
If I simply place libcxx and libcxxabi in-tree, then configure does not pick them up, and they are not built automatically. I placed them in llvm/projects per LLVM's libc++ Standard Library.
Additionally, adding make cxx to the recipe does not work as advertised on the LLVM's libc++ Standard Library page. It results in:
llvm[0]: Constructing LLVMBuild project information.
make: *** No rule to make target `cxx'. Stop.
When I configure LLVM/Clang with --with-libcxx and --with-libcxxabi:
# Issued from a scratch 'build' directory, which is next to the 'llvm' directory.
../llvm/configure --enable-optimized --enable-cxx11 --with-libcxx --with-libcxxabi \
$OTHER_OPTIONS --prefix=/usr/local
then I receive the following:
configure: WARNING: Unknown project (libcxx) won't be configured automatically
configure: WARNING: Unknown project (libcxxabi) won't be configured automatically
libcxx and libcxxabi are literally what LLVM calls them, so I'm not sure what names to use if they are not correct.
I tried to examine configure for what the package names should be, but its not very helpful. See below for the logic.
How do I configure and build Clang with libc++ (when libc++ and libc++ ABI are in-tree)?
Configure logic for --with-XXX is shown below.
this is all I can find (its not very helpful):
-with-* | --with-*)
ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
{ echo "$as_me: error: invalid package name: $ac_package" >&2
{ (exit 1); exit 1; }; }
ac_package=`echo $ac_package| sed 's/-/_/g'`
eval with_$ac_package=\$ac_optarg ;;
Related links:
LLVM/Clang download page
LLVM's libc++ Standard Library page
And this Stack Overflow question is related: When is libc++ sources needed when building Clang from sources?
And this discussion of CFE-Dev mailing list: Questions about libc++ for linux and its git repository (if any). The thread says unpacking libcxx into llcm/projects ensures the headers are copied where Clang expects them during make install. But it does not address the --with-XXX question, it does not discuss why libc++ was not built, and it does not discuss how to get make install to actually install the libraries.
Recipe to fetch and build Clang. It works fine when not including libcxx and libcxxabi.
#! /bin/sh
# Clang 3.5 recipe.
# The script should be run from a scratch directory.
# Fetch
if [ ! -e llvm-3.5.0.src.tar.xz ]; then
wget http://llvm.org/releases/3.5.0/llvm-3.5.0.src.tar.xz
fi
if [ ! -e cfe-3.5.0.src.tar.xz ]; then
wget http://llvm.org/releases/3.5.0/cfe-3.5.0.src.tar.xz
fi
if [ ! -e compiler-rt-3.5.0.src.tar.xz ]; then
wget http://llvm.org/releases/3.5.0/compiler-rt-3.5.0.src.tar.xz
fi
if [ ! -e libcxx-3.5.0.src.tar.xz ]; then
wget http://llvm.org/releases/3.5.0/libcxx-3.5.0.src.tar.xz
fi
if [ ! -e libcxxabi-3.5.0.src.tar.xz ]; then
wget http://llvm.org/releases/3.5.0/libcxxabi-3.5.0.src.tar.xz
fi
if [ ! -e clang-tools-extra-3.5.0.src.tar.xz ]; then
wget http://llvm.org/releases/3.5.0/clang-tools-extra-3.5.0.src.tar.xz
fi
# Cleanup
echo "Cleaning up artifacts"
rm -rf llvm build llvm-3.5.0.src
# LLVM
echo "Unpacking LLVM"
tar xf llvm-3.5.0.src.tar.xz
mv llvm-3.5.0.src/ llvm
# Clang Front End
echo "Unpacking Clang Front End"
cd llvm/tools
tar xf ../../cfe-3.5.0.src.tar.xz
mv cfe-3.5.0.src clang
cd ../../
# Compiler RT
echo "Unpacking Compiler RT"
cd llvm/projects
tar xf ../../compiler-rt-3.5.0.src.tar.xz
mv compiler-rt-3.5.0.src/ compiler-rt
cd ../../
# Extra Tools
echo "Unpacking Extra Tools"
cd llvm/tools/clang/tools/
tar xf ../../../../clang-tools-extra-3.5.0.src.tar.xz
mv clang-tools-extra-3.5.0.src extra
cd ../../../../
# libc++
echo "Unpacking libc++"
cd llvm/projects
tar xf ../../libcxx-3.5.0.src.tar.xz
mv libcxx-3.5.0.src/ libcxx
cd ../../
# libc++ ABI
echo "Unpacking libc++ ABI"
cd llvm/projects
tar xf ../../libcxxabi-3.5.0.src.tar.xz
mv libcxxabi-3.5.0.src/ libcxxabi
cd ../../
# Determine if Apple
IS_DARWIN=`uname -s | egrep -i -c "Darwin"`
if [ $IS_DARWIN -ne 0 ]; then
OTHER_OPTIONS=" --enable-libcpp"
fi
# Configure
echo "Configuring build"
mkdir -p build
cd build
../llvm/configure --enable-optimized --enable-cxx11 --with-libcxx --with-libcxxabi $OTHER_OPTIONS --prefix=/usr/local
# Build
# 'make cxx' for libc++ is from http://libcxx.llvm.org/
echo "Running make"
make cxx
make -j2
RET=$?
if [ $RET -eq 0 ];then
echo "****************************************"
read -p "Press [ENTER] to install, or [CTRL]+C to quit"
sudo make install
fi
# ****************************************
# ****************************************
# Install does not install scan-build and scan-view
# Perform the copy, and/or put them on-path
#sudo cp llvm/projects/compiler-rt/lib/asan/scripts/asan_symbolize.py /usr/local/bin
#sudo 2to3 -w /usr/local/bin/asan_symbolize.py
#sudo mkdir /usr/local/bin/scan-build
#sudo cp -r llvm/tools/clang/tools/scan-build /usr/local/bin
#sudo mkdir /usr/local/bin/scan-view
#sudo cp -r llvm/tools/clang/tools/scan-view /usr/local/bin
This is script which I used to build libcxxabi and libcxx. It use previously built Clang (with GCC (4.8.3 in my case) and GCC STL):
if ( $#argv != 2 ) then
echo "Usage: [32|64] <directory>"
exit
endif
set echo on
set CMake=<CMake executable>
set GCCDir=<recent GCC directory>
set LLVMSourceDir=${PWD}/llvm-${LLVM_VERSION}.src
set LLVMOutOfTreeSourceDir=${PWD}
set LLVMPass1Dir=${PWD}/pass1
set PythonDir=<Python directory>
set InstallDir=${PWD}/$argv[2]
if ( $argv[1] == 32 ) then
set GCC_EHDir=${GCCDir}/lib/gcc/x86_64-redhat-linux/4.8.3/32
set BuildMode="-m32"
set LibDirSuffix=""
else
set GCC_EHDir=${GCCDir}/lib/gcc/x86_64-redhat-linux/4.8.3
set BuildMode="-m64"
set LibDirSuffix="64"
endif
set BuildDir=libcxxabi.build
if ( -d ${BuildDir} ) then
rm -rf ${BuildDir}
endif
mkdir ${BuildDir}
cd ${BuildDir}
${CMake} \
-DCMAKE_BUILD_TYPE="Release" \
-DCMAKE_INSTALL_PREFIX:PATH=${InstallDir} \
-DCMAKE_C_COMPILER=${LLVMPass1Dir}/bin/clang \
-DCMAKE_C_FLAGS=${BuildMode} \
-DCMAKE_CXX_COMPILER=${LLVMPass1Dir}/bin/clang++ \
-DCMAKE_CXX_FLAGS=${BuildMode} \
-DCMAKE_SHARED_LINKER_FLAGS="-L ${GCC_EHDir}" \
-DCMAKE_STATIC_LINKER_FLAGS="${GCC_EHDir}/libgcc_eh.a" \
-DLLVM_FORCE_USE_OLD_TOOLCHAIN=YES \
-DLLVM_PATH=${LLVMSourceDir} \
-DLIBCXXABI_LIBCXX_INCLUDES=${LLVMOutOfTreeSourceDir}/libcxx-${LLVM_VERSION}.src/include \
-DLIBCXXABI_LIBCXX_PATH=${LLVMOutOfTreeSourceDir}/libcxx-${LLVM_VERSION}.src \
-DLIBCXXABI_LIBDIR_SUFFIX=${LibDirSuffix} \
${LLVMOutOfTreeSourceDir}/libcxxabi-${LLVM_VERSION}.src
make
make install
cd ..
set BuildDir=libcxx.build
if ( -d ${BuildDir} ) then
rm -rf ${BuildDir}
endif
mkdir ${BuildDir}
cd ${BuildDir}
${CMake} \
-DCMAKE_BUILD_TYPE="Release" \
-DCMAKE_INSTALL_PREFIX:PATH=${InstallDir} \
-DCMAKE_C_COMPILER=${LLVMPass1Dir}/bin/clang \
-DCMAKE_C_FLAGS=${BuildMode} \
-DCMAKE_CXX_COMPILER=${LLVMPass1Dir}/bin/clang++ \
-DCMAKE_CXX_FLAGS=${BuildMode} \
-DCMAKE_SHARED_LINKER_FLAGS="-L ${GCCDir}/lib${LibDirSuffix}" \
-DLLVM_PATH=${LLVMSourceDir} \
-DLIBCXX_CXX_ABI=libcxxabi \
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=${LLVMOutOfTreeSourceDir}/libcxxabi-${LLVM_VERSION}.src/include \
-DLIBCXX_CXX_ABI_LIBRARY_PATH=${InstallDir}/lib \
-DLIBCXX_LIBDIR_SUFFIX=${LibDirSuffix} \
-DLIT_EXECUTABLE=${LLVMSourceDir}/utils/lit/lit.py \
${LLVMOutOfTreeSourceDir}/libcxx-${LLVM_VERSION}.src
make
make install
cd ..
libc++ and libc++abi aren't maintained to work with configure. I think libc++ might work if you invoke it correctly, but there isn't even a configure script for libc++abi.
See our docs for using cmake with these projects:
# In-tree build:
# Check out libcxx and libcxxabi into llvm/projects
cd llvm
mkdir build && cd build
cmake .. # Linux may require -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
make cxx