47 votes

CMake: comment produire des binaires "comme statique que possible"

Je voudrais avoir le contrôle sur le type de bibliothèques qui se trouve/lié à mon binaires dans CMake. L'objectif final est de générer des exécutables "comme statique du possible", c'est-à-lier de manière statique à l'encontre de toutes les bibliothèques qui n'ont une version statique disponible. C'est important que permettrait la portabilité des fichiers binaires à travers différents systèmes en cours de test.

ATM cela semble bien difficile à atteindre tant la FindXXX.cmake paquets, ou plus précisément de la find_library commande toujours ramasse les bibliothèques dynamiques à chaque fois statique et dynamique sont disponibles.

Conseils sur la façon de mettre en œuvre cette fonctionnalité - le de préférence dans une manière élégante - serait le bienvenu!

28voto

pszilard Points 979

J'ai fait quelques recherches, et bien que je ne pouvais pas trouver une solution satisfaisante au problème, j'ai trouvé une demi-solution.

Le problème de statique construit se résume à 3 choses:

  1. La construction et la liaison du projet interne de bibliothèques.

    Assez simple, il suffit d'inverser la BUILD_SHARED_LIBS interrupteur ON.

  2. Trouver des versions statiques des bibliothèques externes.

    Le seul moyen semble s' CMAKE_FIND_LIBRARY_SUFFIXES à contenir le fichier de suffixe(es) (c'est une liste de priorités).

    Cette solution est tout à fait un "sale" et très bien contre CMake cross plate-forme de leurs aspirations. À mon humble avis, cela devrait être géré en coulisses par CMake, mais que j'ai compris, en raison de la ".lib" une confusion sur Windows, il semble que le CMake développeurs préfèrent la mise en œuvre actuelle.

  3. Lier statiquement contre le système de bibliothèques.

CMake fournit une option LINK_SEARCH_END_STATIC qui est basée sur la documentation: "la Fin d'une ligne de liaison tels que le système statique bibliothèques sont utilisées." On pourrait penser, c'est ça, le problème est résolu. Cependant, il semble que la mise en œuvre actuelle n'est pas à la hauteur. Si l'option est activée, CMake génère un implicite de l'éditeur de liens appeler avec une liste d'arguments qui se termine avec les options passées à l'éditeur de liens, y compris -Wl,-Bstatic. Cependant, ce n'est pas suffisant. Seulement demandant à l'éditeur de liens à lier statiquement une erreur, dans mon cas: /usr/bin/ld: cannot find -lgcc_s. Ce qui manque, c'est dire à gcc en tant que bien que nous avons besoin de la liaison statique par le biais de l' -static argument qui n'est pas généré pour l'éditeur de liens appeler par CMake. Je pense que c'est un bug, mais je n'ai pas réussi à obtenir une confirmation de la part des développeurs encore.

Enfin, je pense que tout cela pourrait et devrait être fait par CMake en coulisses, après tout ce n'est pas si compliqué, sauf que c'est impossible sur Windows - si qui comptent aussi compliqué...

15voto

Jonathan Sternberg Points 2554

Un bien fait FindXXX.cmake fichier comprendra quelque chose pour cela. Si vous regardez dans FindBoost.cmake, vous pouvez définir la Boost_USE_STATIC_LIBS variable pour contrôler si oui ou non elle trouve statique ou des bibliothèques partagées. Malheureusement, une majorité de paquets ne pas le mettre en œuvre.

Si un module utilise la find_library de commande (la plupart le font), alors vous pouvez changer CMake du comportement par le biais de CMAKE_FIND_LIBRARY_SUFFIXES variable. Voici pertinentes CMake code de FindBoost.cmake pour utiliser ce:

IF(WIN32)
    SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
ELSE(WIN32)
    SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
ENDIF(WIN32)

Vous pouvez mettre ceci avant d'appeler find_package, ou, mieux, vous pouvez modifier la .cmake fichiers eux-mêmes et de contribuer à la communauté.

Pour la .cmake fichiers que j'utilise dans mon projet, je vous garde tous dans leur propre dossier dans le contrôle de source. Je l'ai fait parce que je trouve qu'avoir le bon .cmake fichier pour certaines bibliothèques, était incompatible et de garder ma propre copie m'a permis de faire des modifications et de s'assurer que tout le monde qui a extrait le code aurait la même version du système de fichiers.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X