IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Systèmes de compilation Discussion :

[cmake] installation d'une bibliothèque précompilée.


Sujet :

Systèmes de compilation

  1. #1
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut [cmake] installation d'une bibliothèque précompilée.
    Bonjour à tous.
    Je travaille sur deux projets:
    1. Un SDK matérialisé par une bibliothèque partagée ou statique.
    2. Des applications clientes tournant sur plusieurs plateforme, dont Linux et Windows.


    La bibliothèque est gérée avec CMake et doit être compilable avec GCC sous Linux et Visual Studio sous Windows.
    L'application cliente où je rencontre mon problème est compilée sous Windows

    Le SDK installe ses cibles de compilations, et exporte sa configuration d'installation (install(TARGETS SDK EXPORT SDKConfig...) et install(EXPORT SDKConfig ...)).
    Le client utilise find_package(SDK) puis target_link_library(SDK).

    Jusque là, tout va bien, c'est la procédure standard.

    Mon problème se pose avec un détail du SDK.
    La bibliotèque principale du SDK dépend d'une autre, que j'appelerai ici libinterne, compilée en "static mais fpic".
    CMake exige que j'installe aussi cette target libinterne, ce que j'ai fait (install(TARGETS libinterne EXPORT SDKConfig...)).

    Pour la version Linux, la discussion s'arrête là et tout va bien.
    Pour la version windows, il s'avère que libinterne utilise une seconde sous-bibliothèque, détail.lib, dont nous n'avons pas les sources.

    Voici le CMakeLists.txt de libinterne, qui est "add_subdirectory" par celui du SDK. (j'ai seulement retiré les elseif pour les autres plateformes)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    add_library(libinterne STATIC ${SOURCES})
    target_include_directories(libinterne
    PUBLIC
      ${libinterne_INCLUDES}
    )
     
    if (WIN32)
      set(DETAIL_DIR "un chemin dans les sources")
      target_link_libraries(libinterne
      PRIVATE
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${DETAIL_DIR}/détail.lib>
        # $<INSTALL_INTERFACE:détail.lib>
      )
     
      # install(FILES ${DETAIL_DIR}/détail.lib DESTINATION lib)
    endif()
     
    install(TARGETS libinterne
      EXPORT SDKConfig
      RUNTIME DESTINATION bin
      LIBRARY DESTINATION lib
      ARCHIVE DESTINATION lib
    )
    En l'état, le SDK est compilé et installé avec libinterne, mais sans détail.lib.
    L'application cliente se plaint que certains symboles externes ne sont pas définis:
    libinterne.lib(libinterne-win32.obj) : error LNK2019: unresolved external symbol "unsigned char __cdecl DETAIL_fonction1(char *)" (?DETAIL_fonction1@@YAEPAD@Z) referenced in function "long __cdecl Interne::f1(unsigned long,unsigned long)" (?f1@Interne@@YAJKK@Z) [<chemin du fichier vcxproj de l'application client>]
    Si je décommente les deux lignes commentées, l'édition de liens de l'application cliente échoue car
    fatal error LNK1104: cannot open file 'détail.lib [<chemin du fichier vcxproj de l'application client>]'
    À noter, j'ai une autre paire de bibliothèque A et B, qui fonctionnent de la même manière, sans poser problème (SDK dépend de A qui dépend de B, mais B est compilée par le projet).

    Je ne comprends pas plusieurs points, à savoir:
    • Pourquoi le PRIVATE n'est pas honoré: pourquoi l'application cliente doit linker sur détail.lib.
    • Pourquoi les symboles de détail.lib ne sont pas correctement inclus dans libinterne, alors qu'il s'agit de deux bibliothèque statiques.
    • Comment installer détail.lib pour qu'elle soit liée automatiquement, de la même manière que les autres bibliothèques (comme B).


    Du coup, je ne vois pas comment m'en sortir.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Après longue discussion, on est arrivé à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      set(DETAIL_DIR "un chemin dans les sources")
      target_link_libraries(libinterne
      PRIVATE
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${DETAIL_DIR}/détail.lib>
        $<INSTALL_INTERFACE:\${_IMPORT_PREFIX}/lib/détail.lib>
      )
     
      install(FILES ${DETAIL_DIR}/détail.lib DESTINATION lib)
    Le fichier de configuration contient bien target_link_library(${_IMPORT_PREFIX}/lib/détail.lib), exactement comme si la bibliothèque avait été compilée et installée par CMake

    Je ne suis pas sûre que c'est la bonne solution, mais s'en est une qui répond au besoin, et pas trop moche
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Installation d'une bibliothèque
    Par F0ul dans le forum Bibliothèques
    Réponses: 0
    Dernier message: 06/04/2008, 11h32
  2. Erreur apres installation d'une bibliothèque
    Par dedepsg dans le forum Code::Blocks
    Réponses: 2
    Dernier message: 21/05/2007, 10h49
  3. [MikTex] Installation d'une bibliothèque
    Par franc82 dans le forum Distributions
    Réponses: 2
    Dernier message: 29/01/2007, 19h42
  4. Réponses: 7
    Dernier message: 17/12/2006, 01h22
  5. Installation d'une bibliothèque
    Par Empty_body dans le forum JBuilder
    Réponses: 3
    Dernier message: 09/02/2006, 19h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo