Red de conocimiento informático - Material del sitio web - Cómo usar Ninja para construir rápidamente LLVM y Clang

Cómo usar Ninja para construir rápidamente LLVM y Clang

1. Compile llvm/clang/lldb/lld 3.5.0 y otros componentes

Preparación 1.0:

Al menos necesita descargar llvm, cfe, lldb, compilador, desde llvm. org rt, lld y otras versiones 3.5.0 del código.

$tar xf llvm-3.5.0.src.tar.gz

$cd llvm-3.5.0.src

$mkdir -p herramientas/ clang

$mkdir -p herramientas/clang/tools/extra

$ mkdir -p herramientas/lld

$mkdir -p proyectos/compiler-rt

$tar xf cfe-3.5.0.src.tar.xz -C herramientas/clang --strip-components=1

$tar xf compilador-rt-3.5.0. src.tar.xz -C proyectos/compiler-rt --strip-components=1

$tar xf lldb-3.5.0.src.tar.xz -C herramientas/clang/tools/extra - -strip-components=1

$tar xf lldb-3.5.0.src.tar.xz -C herramientas/clang/tools/extra - -strip-components=1

$tar xf lldb-3.5.0.src.tar.xz -C tools/lld --strip-components=1

1.1 Al usar clang --stdlib=libc++, puedes elegir agregar automáticamente - lc++

El componente libc++ puede usar la ABI supc++ de gcc libstdc++, o puede usar c++abi, cxxrt, etc. De hecho, no es necesario agregar -lc++abi automáticamente. De hecho, puede agregar manualmente -lc++abi al vinculador mediante "clang++ -stdlib=libc++".

En el momento del enlace, existe la cuestión de si el DSO es implícito o explícito. Anteriormente, ld vinculaba automáticamente bibliotecas que tenían dependencias introducidas por la biblioteca, pero debido a la incontrolabilidad de este comportamiento, el comportamiento del vinculador ld se modificó para indicar explícitamente todas las bibliotecas que deben vincularse, de modo que -lc++ abi se puede agregar manualmente.

--- llvm-3.0.src/tools/clang/lib/Driver/ToolChain.cpp 2012-03-26 18:49:06.663029075 +0800

+++ llvm -3.0.srcn/tools/clang/ lib/Driver/ToolChain.cpp 2012-03-26 19:36:04.260071355 +0800

@@ -251,6 +251,7 @@

cambiar (Tipo) {

caso ToolChain::CST_ Libcxx:

CmdArgs.push_back("-lc++");

+ CmdArgs. push_back("-lc++abi");

break;

case ToolChain::CST_Libstdcxx:

1.2 Es necesario agregar el modificador -fnolibgcc en sonido metálico ++.

Este interruptor se utiliza principalmente para controlar si se conecta libgcc o libunwind.

Nota: libgcc no es lo mismo que libunwind. Partes de libgcc_eh y supc++ son equivalentes a libunwind.

Nota: libgcc_s y compilador_rt parcial son equivalentes.

Este parche es necesario, no afecta el uso normal de clang de ninguna manera y solo es efectivo cuando se usa el parámetro "-fnolibgcc".

La razón principal para introducir todas las introducciones de desenredado es evitar el problema de que falten símbolos. Los símbolos perdidos se manejan de forma relativamente limpia aquí y se evitan introducciones innecesarias según sea necesario.

--- llvm-static-3.5.0.bak/tools/clang/lib/Driver/Tools.cpp 2014-09-10 13:46:02.581543888 +0800

+++ llvm-static-3.5.0/tools /clang/lib/Driver/Tools.cpp 2014-09-10 16:03:37.559019321 +0800

@@ -2060,9 +2060, 15 @@

".a");

CmdArgs.push_back(Args.MakeArgString(LibClangRT));

- CmdArgs.push_back("-lgcc_s ");

- si (TC.getDriver().CCCIsCXX())

- CmdArgs.push_back("- lgcc_eh");

+ si (Args.hasArg(opciones::OPT_fnolibgcc)) {

+ CmdArgs.push_back("-según-necesario");

+ CmdArgs.push_back("- lunwind");

+ CmdArgs.push_back("-no-no-necesario");

+ CmdArgs.push_back("-lgcc_eh");

+ if ( Args.push_back("-lgcc_eh");

+ }

}

static void addProfileRT(

@@ -7150, 24 +7156,50 @@

bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;

bool StaticLibgcc = Args.hasArg(opciones::OPT_static_libgcc ) ||

Args.hasArg(opciones::OPT_static);

+

+

if (!D.CCCIsCXX( ))

- CmdArgs.push_back("-lgcc");

+ if (Args.hasArg(opciones::OPT_fnolibgcc)) {

+ CmdArgs .push_back("--según sea necesario");

+ CmdArgs.push_back("-lunwind");

+ CmdArgs.push_back("-lunwind")push_back(" -lgcc");

+ if (Args.hasArg(options::OPT_fnolibgcc)) {

+ CmdArgs.push_back("--según sea necesario");

+ CmdArgs.push_back("-lunwind");

+ CmdArgs.push_back("-lunwind") {

+ D.CCCIsCXX()push_back("- lgcc_s");

if (!D.CCCIsCXX())

CmdArgs.push_back("-no-según-necesario");

}

Si (S

taticLibgcc && !isAndroid)

- CmdArgs .push_back("-lgcc_eh");

+ if (Args.hasArg(options::OPT_fnolibgcc)) {

+ CmdArgs.push_back("--según sea necesario");

+ CmdArgs.push_back("-lunwind");

+ CmdArgs.push_back("-lgcc") ;

+ if (Args.hasArg(opciones::OPT_ fnolibgcc)) {

+ CmdArgs.push_back("-según sea necesario");

+ CmdArgs.push_back("-lunwind");

+ CmdArgs.push_back("-no-necesario");

+ CmdArgs.push_back("-lunwind");

+ D.CCCIsCXX()push_back("-no-según-necesario");

+ } else

+ CmdArgs.push_back("-lgcc" );

// Según Android ABI, si usamos libgc no estático para vincular, debemos vincular libdl.

--- llvm-static-3.5.0.bak/tools/clang/include/clang/Driver/Options.td 2014-08-07 12:51:.51.000000000 +0800

+++ llvm-static-3.5.0/tools/clang/include/clang/Driver/Options.td 2014-09-10 13:36:34.598511176 +0800

@@ -788 ,6 +788,7 @@

def fomit_frame_pointer : Bandera<["-"], "fomit-frame-pointer">, Grupo;

def fopenmp : Bandera< ;["-"], "fopenmp">, Grupo, Banderas<[CC1Option, NoArgumentUnused]>;

def fopenmp_EQ: Unido<["-"], "fopenmp= " > , Grupo, Banderas<[CC1Option]>;

+def fnolibgcc: Bandera<["-"], "fnolibgcc">, Grupo, Banderas& lt;[CC1Option, NoArgumentUnused] >;

def fnoo_optimize_sibling_calls: Bandera<["-"], "fno_optimize-sibling-calls">;, Grupo;

def foptimize_sibling_calls: Bandera<[" -"], "foptimize-sibling-calls">;, Grupo;

def force__ cpusubtype__ALL : Bandera<["-"], "force_cpusubtype_ALL">;

Otros parches para 1.3 llvm.

llvm/clang coloca la ruta al código rígido de la cadena de herramientas gcc en su código, verifique tools/clang/lib/Driver/ToolChains.cpp.

Busque cadenas como x86_64-redhat-linux.

Si no hay una cadena triple de gcc para su sistema, agréguela usted mismo.

Esta cadena de tres capas es principalmente para que llvm/clang busque archivos de encabezado gcc, etc., y no afecta la cadena de herramientas que se construirá en este artículo

1.4 Construcción clang/llvm/lldb

p>

Este artículo usa ninja. Por cierto, tanto llvm.configure como cmake admiten ninja. Tal vez porque el proyecto es demasiado grande, los archivos de proyecto de estos dos métodos de construcción tienen varios defectos (reflejados principalmente en las opciones de cambio, como configurar pero no cmake, etc.). llvm-3.4.1 se debe a errores en el archivo del proyecto cmake, lo que llevó al lanzamiento de la versión 3.4.2.

En resumen, el método cmake+ninja es uno de los métodos de compilación más rápidos disponibles actualmente, reduciendo el tiempo de compilación a más de la mitad.

mkdir build

cd build

cmake \

-G Ninja \

-DCMAKE_INSTALL_PREFIX=/usr \

-DCMAKE_BUILD_TYPE="Lanzamiento" \

-DCMAKE_CXX_FLAGS="-std=c++11" \

-DBUILD_SHARED_LIBS=OFF \

-DLLVM_ENABLE_PIC=ON \

-DLLVM_TARGETS_TO_BUILD=" todos" \

-DCLANG_VENDOR="MyOS" .

ninja

instalación ninja

Si el sistema ya tiene una versión clang/clang++ disponible, puedes agregar:

-DCMAKE_C_COMPILER=clang \

-DCMAKE_CXX_COMPILER= clang++ \

Esto utilizará el clang++ del sistema para construir llvm/clang

2.

Simplemente busque algunos c/cpp/objc/etc simples para compilar y probar. Se pueden completar pruebas completas mediante ninja check-all en el momento de la compilación

3.

3.1 Obtener el código de /pathscale/libunwind.

Existen muchas implementaciones de libunwind, como libunwind de gnu, libunwind de path64 y Unwinder de libcxxabi.

Las siguientes son algunas notas:

1) A libunwind de gnu le faltan símbolos y conflictos.

2) libcxxabi viene con Unwinder para mac e ios, es decir, sólo se puede construir en darwin. Actualmente, la implementación de Linux aún no está completa. Cuando se complete la implementación de Linux, es posible que la implementación de desconexión de path64 ya no sea necesaria.

Actualmente, recomendamos utilizar la implementación de escala de ruta de unwind.

mkdir -p build

cd build

cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_C_FLAGS="-m64" ...

ninja

mkdir -p /usr/lib

cp src/libunwind.so /usr/lib

cp src/libunwind.a /usr/ lib

3.2 compila libcxx por primera vez.

Es necesario compilar libcxx primero para que libcxxabi pueda compilarse más tarde. El libcxx compilado aquí en realidad usa libgcc/stdc++/supc++ de gcc.

Añade este parche para desactivar la importación de libgcc:

diff -Nur libcxx/cmake/config-ix.cmake libcxxn/cmake/config-ix.cmake

--- libcxx/cmake/config-ix .cmake 2014-06-25 06:57:50.000000000 +0800

+++ libcxxn/cmake/config-ix.cmake 2014-06-25 09 :05:24.980350544 +0800

@@ -28,5 +28, 4 @@

check_library_exists(c printf "" LIBCXX_HAS_C_LIB)

check_library_exists( m ccos "" LIBCXX_HAS_M_LIB)

check_library_ existe(rt clock_gettime "" LIBCXX_HAS_RT_LIB)

-check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB)

Compilar e instalar:

p>

mkdir build

cd build

cmake (

-G Ninja (

-DCMAKE_INSTALL_PREFIX=/ usr (

-DCMAKE_C_COMPILER=clang (

-DCMAKE_CXX_COMPILER=clang++ (

...

ninja

instalación ninja

3.3 Pruebe la primera compilación de libcxx

Utilice "clang++ -stdlib=libc++ -o test test.cpp -lstdc++" para compilar código C++ simple y verificar si hay errores. Si el parche de enlace c++abi se aplicó en la versión anterior de clang, c++abi no se encontrará aquí, simplemente omítalo)

Utilice "ldd test" para verificar el enlace dinámico binario de prueba. Uso de la biblioteca. Puede ver que la prueba depende de libgcc_s/libc++/libstdc++. (Es un poco frustrante, ¿verdad? ¿Estás usando libc++ pero tienes que confiar en libstdc++?)