Comment dire à CMake de créer un lien dans une bibliothèque statique dans le répertoire source?

96

J'ai un petit projet avec un Makefile que j'essaie de convertir en CMake, principalement juste pour acquérir de l'expérience avec CMake. Pour les besoins de cet exemple, le projet contient un fichier source (C ++, bien que je ne pense pas que le langage soit particulièrement pertinent) et un fichier de bibliothèque statique que j'ai copié ailleurs. Supposons pour les arguments que le code source de la bibliothèque n'est pas disponible; Je n'ai que le fichier .a et l'en-tête correspondant.

Mon Makefile fait à la main contient cette règle de construction:

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

qui fonctionne très bien. Comment dire à CMake de reproduire cela? Pas littéralement ce makefile exact, bien sûr, mais quelque chose qui inclut une commande de liaison équivalente. J'ai essayé les moyens évidents mais naïfs, comme

add_executable(main main.cpp libbingitup.a)

ou

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

ainsi que diverses choses avec link_directories(.)ou add_library(bingitup STATIC IMPORTED)etc., mais rien à ce jour qui aboutisse à un lien réussi. Que dois-je faire?


Détails de la version: CMake 2.8.7 sous Linux (Kubuntu 12.04) avec GCC 4.6.3

David Z
la source

Réponses:

121

CMake préfère transmettre le chemin d'accès complet aux bibliothèques de liens, donc en supposant que libbingitup.a est dans ${CMAKE_SOURCE_DIR}, faire ce qui suit devrait réussir:

add_executable(main main.cpp)
target_link_libraries(main ${CMAKE_SOURCE_DIR}/libbingitup.a)
Fraser
la source
2
Super, ça marche, merci! Cela semble un peu hackish d'avoir à mettre explicitement le chemin complet ici, mais je suppose que c'est juste la manière CMake ...
David Z
4
Je suis d'accord que cela semble exagéré ici, mais spécifier explicitement le chemin complet paie des dividendes si vous avez plusieurs versions différentes de la même bibliothèque installée.
Fraser
1
Incroyable, comme d'habitude! Dans mon cas, résolu un problème de bibliothèques dépendant d'une autre bibliothèque dynamique construite qui dépendait d'une bibliothèque statique: les bibliothèques dépendantes essayaient également de se lier à cette bibliothèque statique.
Antonio
1
Comment Main connaît-il les répertoires d'inclusion?
ManuelSchneid3r
3
Vous devrez utiliser target_include_directoriesou include_directories(le premier est le moyen préféré car il est plus spécifique).
Fraser
31

Si vous ne souhaitez pas inclure le chemin complet, vous pouvez faire

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

bingitup est le même nom que vous donneriez à une cible si vous créez la bibliothèque statique dans un projet CMake:

add_library(bingitup STATIC bingitup.cpp)

CMake ajoute automatiquement le libà l'avant et .aà la fin sous Linux, et .libà la fin sous Windows.

Si la bibliothèque est externe, vous pouvez ajouter le chemin d'accès à la bibliothèque en utilisant

link_directories(/path/to/libraries/)
Cris Luengo
la source
1
Et s'il y a des fichiers .a et .so avec le même nom, comment indiquez-vous que vous voulez lier le .a ou le .so dans ce cas?
George
1
@George: Vous ne pouvez pas. Si les deux types sont présents, incluez le nom complet du fichier que vous souhaitez lier.
Cris Luengo
21

J'ai trouvé cela utile ...

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

De leur exemple:

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)
étu
la source
3
Et les INCLUDE_DIRECTORIES?
kyb
1
Cela ne fonctionne que si la bibliothèque fait partie de la construction de cmake, mais les bibliothèques étrangères cela ne fonctionne pas
eigenfield
la question dit "le projet contient un fichier source (C ++, bien que je ne pense pas que le langage soit particulièrement pertinent) et un fichier de bibliothèque statique que j'ai copié d'ailleurs."
STU