web-dev-qa-db-fra.com

Cmake: Comment produire des binaires "aussi statiques que possible"

J'aimerais avoir le contrôle du type des bibliothèques qui se trouvent trouvés/liés à mes fichiers binaires dans CMAKE. L'objectif final est de générer des fichiers binaires "comme statique que possible" qui consiste à lier statilement à chaque bibliothèque qui dispose d'une version statique disponible. Ceci est important comme permettrait la transférabilité des fichiers binaires à travers différents systèmes lors des tests.

ATM Cela semble être assez difficile à atteindre comme des packages Findexxx.Cakake, ou plus précisément la commande Find_Library reprend toujours les bibliothèques dynamiques chaque fois que les deux statiques et dynamiques sont disponibles.

Conseils sur la manière de mettre en œuvre cette fonctionnalité - de préférence d'une manière élégante - serait très bienvenue!

47
pszilard

J'ai fait une certaine enquête et même si je ne pouvais pas trouver une solution satisfaisante au problème, j'ai trouvé une demi-solution.

Le problème des constructions statiques se résume à 3 choses:

  1. Construire et relier les bibliothèques internes du projet.

    Assez simple, il suffit de retourner le BUILD_SHARED_LIBS Switch OFF.

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

    La seule façon semble définir CMAKE_FIND_LIBRARY_SUFFIXES Pour contenir le suffixe de fichier souhaité (ES) (c'est une liste de priorités).

    Cette solution est une "sale" une "sale" et beaucoup contre les aspirations croisées de Clake. IMHO Cela devrait être manipulé dans les coulisses par cmake, mais aussi loin que j'ai compris, à cause de la confusion ".lib" sur Windows, il semble que les développeurs de cumake préfèrent la mise en œuvre actuelle.

  3. Reliant statiquement les bibliothèques système.

Cumake fournit une option LINK_SEARCH_END_STATIC qui basé sur la documentation: "mettre fin à une ligne de liaison de telle sorte que les bibliothèques du système statique soient utilisées." On pourrait penser que c'est cela, le problème est résolu. Cependant, il semble que la mise en œuvre actuelle ne soit pas à la hauteur de la tâche. Si l'option est allumée, Cumake génère un appel implicite avec une liste d'arguments qui se termine par les options transmises à la lieur, y compris -Wl,-Bstatic. Ce n'est pas sufisant. Ne demandez que le lien de lien de lier statilement des résultats statilement dans une erreur, dans mon cas: /usr/bin/ld: cannot find -lgcc_s. Ce qui manque, c'est dire à GCC aussi que nous avons besoin de lien entre la statique par le biais de l'-static argument qui est non généré à l'appel de la liaison par cmake. Je pense que c'est un bug, mais je n'ai pas encore réussi à obtenir une confirmation des développeurs.

Enfin, je pense que tout cela pourrait et devrait être fait par cmake dans les coulisses, après tout ce n'est pas si compliqué, sauf qu'il est impossible sur Windows - si cela comptent comme compliqué ...

28
pszilard

Un fichier FINDXXX.CMAKE bien fabriqué comprendra quelque chose pour cela. Si vous regardez dans Windboost.cmake, vous pouvez définir la variable BOOST_USE_STATIC_LIBS pour contrôler s'il trouve ou non des bibliothèques statiques ou partagées. Malheureusement, une majorité de forfaits ne mettent pas en œuvre cela.

Si un module utilise la commande Find_Library (la plupart de), vous pouvez modifier le comportement de CUPE'S à travers CUKE_FIND_LIBRY_SUFFIXES Variable. Voici le code CUKE pertinent de WindBoost.cmake pour utiliser ceci:

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 soit mettre cela avant d'appeler Find_Package, soit mieux, vous pouvez modifier les fichiers .cmake eux-mêmes et contribuer à la communauté.

Pour les fichiers .cmake que j'utilise dans mon projet, je les conserve dans leur propre dossier dans le contrôle de la source. Je l'ai fait parce que j'ai constaté que le fait d'avoir le bon fichier .CMake pour certaines bibliothèques était incompatible et que la conservation de ma propre copie m'a permis de modifier et de vous assurer que tous ceux qui ont vérifié le code auraient les mêmes fichiers système de construction.

15