Как заставить clang использовать библиотеку по умолчанию?
Я создаю clang clang для libС++, libС++ abi, compiler-rt в следующих шагах:
-
Чтобы загрузить (и обновить) llvm и подпроекты, я использую следующий script:
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk clang/tools/extra
svn co http://llvm.org/svn/llvm-project/lldb/trunk lldb
svn co http://llvm.org/svn/llvm-project/lld/trunk lld
svn co http://llvm.org/svn/llvm-project/polly/trunk polly
cd ../projects/
svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
svn co http://llvm.org/svn/llvm-project/libunwind/trunk libunwind
svn co http://llvm.org/svn/llvm-project/openmp/trunk openmp
svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi
svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx
-
Прежде всего, я создаю llvm, clang, libunwind для libgcc и libstdС++ с помощью gcc и устанавливаю их в /usr/local
. Во всех следующих шагах, кроме последнего, я использую этот свежий clang
/clang++
.
- Затем я отдельно создаю libunwind, как 32-битную, так и 64-битную версии (они необходимы, как будет дальше, потому что asan нуждается в 32-битных версиях некоторых библиотек во время окончательной компиляции всего дерева проектов) и установите его в
/usr/local/lib
и /usr/local/lib32
соответственно (также я обновляю LD_LIBRARY_PATH
соответственно).
- Создайте библиотеку ABC libcxxrt как с 32-разрядной, так и с 64-разрядной версиями и установите их правильно.
- Создайте libcxx для libcxxrt как 32-разрядных, так и 64-разрядных версий и установите их правильно.
- Затем создайте libС++ abi для libС++ как 32-разрядных, так и 64-разрядных версий и установите их правильно.
- Затем создайте libС++ для libС++ abi как для 32-разрядных, так и для 64-разрядных версий и правильно установите их поверх предыдущей версии, связанной с libcxxrt.
- В конце концов я строю все дерево проекта против libС++, libС++ abi, libunwind, compiler-rt и устанавливаю его поверх старого clang в
/usr/local
.
(Я почти уверен, что здесь нет лишнего шага.)
На последнем этапе у меня проблема: мне нужно добавить дополнительные параметры в компоновщик (я добавляю их в CMAKE_EXE_LINKER_FLAGS
и CMAKE_SHARED_LINKER_FLAGS
) -lunwind
и -lc++abi
. Более того, каждый раз, когда я использую результирующий clang++
с -stdlib=libc++
и compiler-rt (или, в равной степени, CLANG_DEFAULT_CXX_STDLIB=libc++
и CLANG_DEFAULT_RTLIB=compiler-rt
), в моих проектах мне приходится делать это снова и снова. Это раздражает. Скажем, сгенерированный Qt Creator проект CMakeLists.txt
должен быть исправлен вручную или cmake-gui
.
Как сделать драйвер clang
для автоматического указания этих параметров на ld
во время выполнения? Есть ли что-то похожее на механизм RPATH
? Или существует определенная переменная CMake (указанная до процесса построения llvm) для достижения желаемого поведения?
Могу ли я использовать RPATH
для моих целей?
Конечно, я не хочу создавать некоторые bash - script подобные обертки (похожие на clang++-libc++
), чтобы указать дополнительные параметры. Я хочу, чтобы библиотеки были жестко закодированы где-то в самом двоичном файле clang
.
Ответы
Ответ 1
Предлагается несколько обходных решений. Я закончил со следующим обходным путем:
mkdir build
cd build
# backup:
cp -vaf /usr/local/lib/libc++.{a,so.1.0} /usr/local/lib/libc++abi.{a,so.1.0} /usr/local/lib/libunwind.{a,so.1.0} .
clang -shared -fPIC -pthread -o fuse.so -Wl,--whole-archive libc++.a libc++abi.a libunwind.a -Wl,--no-whole-archive -ldl -lm
ar x libc++.a
ar x libc++abi.a
ar x libunwind.a
ar rc fuse.a *.o
sudo chown root:root fuse.*
sudo cp -vaf fuse.so /usr/local/lib/
sudo ln -svf /usr/local/lib/libc++.so.1 /usr/local/lib/fuse.so
sudo cp -vaf fuse.a /usr/local/lib/
sudo mv -vf /usr/local/lib/libc++.a /usr/local/lib/libc++.a.bak
sudo ln -svf /usr/local/lib/libc++.a /usr/local/lib/fuse.a
Он объединяет все используемые библиотеки (libc++
, libc++abi
и libunwind
) в один единственный файл *.a
или *.so
. Затем libc++.a
и libc++.so
заменяются (ссылками на) результирующие собранные файлы, сохраняя предыдущие версии для возможной резервной копии.
Он отлично работает для меня.
Но это не ответ. Возможно, когда-нибудь clang
не будет иметь такую проблему прямо из коробки.