Como faço para dizer ao CMake para vincular a uma biblioteca estática no diretório de origem?

98

Eu tenho um pequeno projeto com um Makefile que estou tentando converter para CMake, principalmente para obter experiência com o CMake. Para os fins deste exemplo, o projeto contém um arquivo de origem (C ++, embora eu não ache que a linguagem seja particularmente relevante) e um arquivo de biblioteca estática que copiei de outro lugar. Suponha, para fins de argumentação, que o código-fonte da biblioteca não esteja disponível; Tenho apenas o arquivo .a e o cabeçalho correspondente.

Meu Makefile feito à mão contém esta regra de construção:

main: main.o libbingitup.a
    g++ -o main main.o libbingitup.a

que funciona bem. Como faço para dizer ao CMake para reproduzir isso? Não literalmente esse makefile exato, é claro, mas algo que inclui um comando de vinculação equivalente. Tentei maneiras óbvias, mas ingênuas, como

add_executable(main main.cpp libbingitup.a)

ou

add_executable(main main.cpp)
target_link_libraries(main libbingitup.a)

bem como várias coisas com link_directories(.)ou add_library(bingitup STATIC IMPORTED)etc., mas nada até agora que resulte em uma ligação bem-sucedida. O que devo fazer?


Detalhes da versão: CMake 2.8.7 no Linux (Kubuntu 12.04) com GCC 4.6.3

David Z
fonte

Respostas:

123

O CMake favorece a passagem do caminho completo para vincular as bibliotecas, portanto, supondo que libbingitup.a esteja disponível ${CMAKE_SOURCE_DIR}, faça o seguinte deve ser bem-sucedido:

add_executable(main main.cpp)
target_link_libraries(main ${CMAKE_SOURCE_DIR}/libbingitup.a)
Fraser
fonte
2
Ótimo, isso funciona, obrigado! Parece um pouco hackeado ter que colocar o caminho completo explicitamente aqui, mas acho que é apenas o jeito CMake ...
David Z
4
Concordo que parece exagero aqui, mas especificar explicitamente o caminho completo paga dividendos se você tiver várias versões diferentes da mesma lib instalada.
Fraser
1
Incrível, como sempre! No meu caso, resolvi um problema de bibliotecas dependendo de outra biblioteca dinâmica construída que dependia de uma biblioteca estática: as bibliotecas dependentes também estavam tentando se vincular a essa biblioteca estática.
Antonio
1
Como o main sabe sobre os diretórios de inclusão?
ManuelSchneid3r
3
Você precisaria usar target_include_directoriesou include_directories(o primeiro é a forma preferida, pois é mais específico).
Fraser
32

Se não quiser incluir o caminho completo, você pode fazer

add_executable(main main.cpp)
target_link_libraries(main bingitup)

bingitup é o mesmo nome que você daria a um destino se criar a biblioteca estática em um projeto CMake:

add_library(bingitup STATIC bingitup.cpp)

O CMake adiciona automaticamente o libna frente e .ano final no Linux e .libno final no Windows.

Se a biblioteca for externa, você pode querer adicionar o caminho para a biblioteca usando

link_directories(/path/to/libraries/)
Cris Luengo
fonte
1
E se houver arquivos .a e .so com o mesmo nome, como você especifica que deseja vincular ao .a ou .so neste caso?
George,
1
@George: Você não pode. Se você tiver os dois tipos presentes, inclua o nome completo do arquivo ao qual deseja vincular.
Cris Luengo
21

Eu achei isso útil ...

http://www.cmake.org/pipermail/cmake/2011-June/045222.html

Do exemplo deles:

ADD_LIBRARY(boost_unit_test_framework STATIC IMPORTED)
SET_TARGET_PROPERTIES(boost_unit_test_framework PROPERTIES IMPORTED_LOCATION /usr/lib/libboost_unit_test_framework.a)
TARGET_LINK_LIBRARIES(mytarget A boost_unit_test_framework C)
coisas
fonte
3
E quanto a INCLUDE_DIRECTORIES?
kyb
1
Isso só funciona se a biblioteca for parte da compilação do cmake, mas os estrangeiros não funcionam
eigenfield
a pergunta diz "o projeto contém um arquivo de origem (C ++, embora eu não ache que a linguagem seja particularmente relevante) e um arquivo de biblioteca estática que copiei de outro lugar."
stu