Cmake no puede encontrar la biblioteca usando “link_directories”

I Ubuntu, estoy aprendiendo sobre cmake y make, y solo estoy probando un ejemplo simple. Tengo dos directorios: src y build . En src , tengo dos archivos: main.cpp y CMakeLists.txt , que tiene (solo) el siguiente texto:

 add_executable(test main.cpp) link_directories(/usr/lib/x86_64-linux-gnu) target_link_libraries(test protobuf) 

En /usr/lib/x86_64-linux-gnu , hay una biblioteca compartida llamada libprotobuf.so , con la que quiero vincular. Mi main.cpp usa funciones en esta biblioteca, al incluir el archivo de cabecera releveant, #include .

Ahora, en mi directorio de build , ejecuto cmake ../src , y luego make . Sin embargo, luego recibo errores del enlazador que me dicen que hay referencias indefinidas a algunas de las funciones en la biblioteca protobuf. Si realizo una búsqueda a través de todos los archivos y subdirectorios en build , no se menciona nada relacionado con protobuf.

Sin embargo, si link_directories línea link_directories en mi archivo CMakeLists.txt , y en su lugar escribo la ruta completa a la biblioteca al especificar el ejecutable, es decir, target_link_libraries(test /usr/lib/x86_64-linux-gnu/libprotobuf.so) , comstack y enlaza bien.

¿Por qué link_directories no permite que cmake encuentre esta biblioteca?

No use link_directories como este en CMake.

Este es un error común de los principiantes, ya que muchos otros entornos de comstackción funcionan de esta manera, pero en CMake solo está pidiendo problemas. Incluso la página de manual específicamente desaconseja:

Tenga en cuenta que este comando [ link_directories ] rara vez es necesario. Las ubicaciones de biblioteca devueltas por find_package() y find_library() son rutas absolutas. Pase estas rutas absolutas de archivo de biblioteca directamente al comando target_link_libraries() . CMake se asegurará de que el enlazador los encuentre.

Por lo tanto, siempre pase las rutas absolutas a target_link_libraries y use find_library para resolver el directorio de enlaces:

 find_library(PROTOBUF_LIBRARY protobuf HINTS /usr/lib/x86_64-linux-gnu) target_link_libraries(test PUBLIC ${PROTOBUF_LIBRARY}) 

Esto tiene la gran ventaja de que probablemente obtendrá un diagnóstico en CMake configure time si no se puede encontrar la biblioteca esperada, en lugar de un error de enlazador aleatorio en tiempo de comstackción. Además, esto permite al usuario especificar una ubicación de biblioteca a través de la GUI si la máquina de destino tiene un diseño de directorio no estándar.

Por lo tanto, si no funciona de inmediato, asegúrese de verificar el resultado de la llamada find_library y consulte la página de manual para buscar por qué no encuentra su biblioteca como estaba previsto.

Asegúrese de que su llamada a link_directories tenga lugar antes de su llamada al add_executable correspondiente.

target_link_libraries erróneamente que solo tenía que estar antes de la llamada a target_link_libraries , pero ese no es el caso. Después de mover la llamada, la biblioteca está vinculada correctamente.

Aquí hay un extracto de la documentación :

link_directories (directory1 directory2 …): especifique las rutas en las que el enlazador debe buscar bibliotecas. El comando se aplicará solo a los objectives creados después de que se llame . Las rutas relativas dadas a este comando se interpretan como relativas al directorio de origen actual; consulte CMP0015.

El comando

add_executable (prueba main.cpp)

crea una prueba de nombres de destino. También debes poner el comando link_directories encima de add_executable.

Asegúrese de que el pedido sea link_directories, establezca PROJECT_LINK_LIBS, add_executable y luego target_link_libraries.

A continuación se muestra un ejemplo para demostrarlo:

 cmake_minimum_required(VERSION 2.8.9) project (Logging) include_directories(include) file(GLOB LOGGINGSOURCES "libsrc/*.cpp") file(GLOB SOURCES "src/*.cpp") add_library(convertString SHARED ${LOGGINGSOURCES}) install(TARGETS convertString DESTINATION /root/Deepak/) link_directories( /root/Deepak/ ) set(PROJECT_LINK_LIBS libconvertString.so) add_executable(hello ${SOURCES}) target_link_libraries(hello ${PROJECT_LINK_LIBS} )