una programacion librerías librerias libreria lenguaje entre dinámicas dinamicas dinamica diferencia dev desarrolladas crear creacion crea con compilar como biblioteca gcc cmake lto

programacion - Uso de la optimización de tiempo de enlace de GCC con bibliotecas enlazadas estáticas



diferencia entre biblioteca y libreria en programacion (1)

Estoy tratando de usar las optimizaciones de tiempo de enlace con la -flto de GCC (6.1.1).

Si bien funciona bien con mi código, no se vincula con una biblioteca estática vinculada. También estoy creando y enlazando con mi proyecto (que es Engine y la biblioteca es glsl-optimizer , solo como referencia).

Aquí está la salida:

... /usr/bin/ranlib: ir_expression_flattening.cpp.o: plugin needed to handle lto object /usr/bin/ranlib: opt_function_inlining.cpp.o: plugin needed to handle lto object /usr/bin/ranlib: opt_copy_propagation_elements.cpp.o: plugin needed to handle lto object ...

Y después de eso, por supuesto, recibo varias "referencias indefinidas" a algunas funciones.

Investigué un poco y descubrí que podría deberse a ar y debería intentar usar gcc-ar , pero no estoy seguro de cómo podría hacerlo.

Además, estoy usando CMake que no es compatible con lto (excepto en el compilador de Intel en algunas plataformas, así que leo ...). Aunque intenté usar:

set_property(TARGET glsl_optimizer PROPERTY INTERPROCEDURAL_OPTIMIZATION True)

Lo que no funcionó.

También, probé el -fuse-linker-plugin de GCC -fuse-linker-plugin que no funcionó.

¿Supongo que tendré que hacerlo manualmente de la manera antigua directamente usando gcc-ar , o tal vez hay algún otro método?


Aquí hay un proyecto MCVE CMake que reproduce el problema:

$ ls -R hellow hellow: CMakeLists.txt hello.c libhello.c $ cat hellow/CMakeLists.txt cmake_minimum_required (VERSION 2.6) project (hellow) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto") #SET(CMAKE_AR "gcc-ar") #SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>") #SET(CMAKE_C_ARCHIVE_FINISH true) add_library(hello STATIC libhello.c) add_executable(hellow hello.c) target_link_libraries(hellow hello) add_dependencies(hellow hello) $ cat hellow/hello.c extern void hello(void); int main(void) { hello(); return 0; } $ cat hellow/libhello.c #include <stdio.h> void hello(void) { puts("Hello"); }

La configuración es buena:

$ mkdir build_hellow $ cd build_hellow/ $ cmake ../hellow -- The C compiler identification is GNU 5.4.0 -- The CXX compiler identification is GNU 5.4.0 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done -- Generating done -- Build files have been written to: /home/imk/dev/so/build_hellow

La construcción falla según el problema:

$ make Scanning dependencies of target hello [ 25%] Building C object CMakeFiles/hello.dir/libhello.c.o [ 50%] Linking C static library libhello.a /usr/bin/ar: CMakeFiles/hello.dir/libhello.c.o: plugin needed to handle lto object /usr/bin/ranlib: libhello.c.o: plugin needed to handle lto object [ 50%] Built target hello Scanning dependencies of target hellow [ 75%] Building C object CMakeFiles/hellow.dir/hello.c.o [100%] Linking C executable hellow /tmp/ccV0lG36.ltrans0.ltrans.o: In function `main'': <artificial>:(.text+0x5): undefined reference to `hello'' collect2: error: ld returned 1 exit status CMakeFiles/hellow.dir/build.make:95: recipe for target ''hellow'' failed make[2]: *** [hellow] Error 1 CMakeFiles/Makefile2:67: recipe for target ''CMakeFiles/hellow.dir/all'' failed make[1]: *** [CMakeFiles/hellow.dir/all] Error 2 Makefile:83: recipe for target ''all'' failed make: *** [all] Error 2

Hay más de una solución. Una es descomentar las 3 líneas comentadas en CMakeLists.txt arriba. Entonces:

$ cmake ../hellow/ -- The C compiler identification is GNU 5.4.0 -- The CXX compiler identification is GNU 5.4.0 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done -- Generating done -- Build files have been written to: /home/imk/dev/so/build_hellow $ make Scanning dependencies of target hello [ 25%] Building C object CMakeFiles/hello.dir/libhello.c.o [ 50%] Linking C static library libhello.a [ 50%] Built target hello Scanning dependencies of target hellow [ 75%] Building C object CMakeFiles/hellow.dir/hello.c.o [100%] Linking C executable hellow [100%] Built target hellow $ ./hellow Hello

Esta solución hace uso de los siguientes hechos.

El problema de construcción:

/usr/bin/ar: CMakeFiles/hello.dir/libhello.c.o: plugin needed to handle lto object ... /usr/bin/ranlib: libhello.c.o: plugin needed to handle lto object

puede resolverse dando a ar y ranlib la opción:

--plugin=$(gcc --print-file-name=liblto_plugin.so)

Sin embargo, GNU ranlib es simplemente un sinónimo de ar -s , y gcc-ar es una envoltura para ar que proporciona ese complemento.

La plantilla de compilación de CMake para una biblioteca estática de C es:

CMAKE_C_ARCHIVE_CREATE ( = <CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>) CMAKE_C_ARCHIVE_FINISH ( = <CMAKE_RANLIB> <TARGET>)

que para GNU ar es equivalente a:

CMAKE_C_ARCHIVE_CREATE ( = <CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>) CMAKE_C_ARCHIVE_FINISH ( = true) # Or any other no-op command

Así que con estas configuraciones más:

SET(CMAKE_AR "gcc-ar")

estamos bien.

Para un proyecto de C ++, por supuesto, establece CMAKE_CXX_ARCHIVE_CREATE y CMAKE_CXX_ARCHIVE_FINISH