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 que 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!
- Pas tout à fait dupe de: stackoverflow.com/questions/2113231/... , qui est GCC-spécifique.
- En fait, non seulement que c'est gcc spécifique, c'est un inconvénient de la solution ainsi. Voir mon commentaire à l'autre question.
- Avez-vous finalement trouvé la solution? Je suis en train de faire la même chose avec g++.
- Quelle est la "bonne façon" de la "bosse" une intéressante question qui reste sans réponse adéquate?
- pas sûr.. mais c'est certainement une question intéressante 🙂
- Bosse en définissant un bounty.
Vous devez vous connecter pour publier un commentaire.
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:
Des capacités et de liaison du projet de bibliothèques internes.
Assez simple, il suffit d'inverser le
BUILD_SHARED_LIBS
commutateurOFF
.Trouver des versions statiques des bibliothèques externes.
Le seul moyen semble être la mise en
CMAKE_FIND_LIBRARY_SUFFIXES
pour 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.
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 la-static
argument qui est pas généré à 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 comme compliqué...
BUILD_SHARED_LIBS
off (donc ne pas construire des bibliothèques partagées)?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 cette:
Vous pouvez soit 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.