Apprendre à compiler des choses à partir des sources (sous Unix / Linux / OSX)

47

Bien que j'installe des logiciels à partir de packages (MacPorts / apt-get) autant que possible, je me trouve souvent dans l'obligation de compiler des packages à partir des sources. ./configure && make && sudo make installest généralement suffisant, mais parfois cela ne fonctionne pas - et quand cela ne fonctionne pas, je suis souvent coincé. Cela concerne presque toujours les autres dépendances de la bibliothèque.

J'aimerais apprendre ce qui suit:

  • Comment puis-je savoir quels arguments passer ./configure?
  • Comment fonctionnent les bibliothèques partagées sous OS X / Linux - où elles résident sur le système de fichiers, comment les ./configure && maketrouve, ce qui se passe réellement quand elles sont liées
  • Quelles sont les différences réelles entre une bibliothèque partagée et une bibliothèque liée statiquement? Pourquoi ne puis-je pas tout lier de manière statique (la RAM et l’espace disque sont bon marché de nos jours) et éviter ainsi d’étranges conflits de versions de bibliothèques?
  • Comment puis-je savoir quelles bibliothèques j'ai installées et quelles versions?
  • Comment puis-je installer plus d'une version d'une bibliothèque sans casser mon système normal?
  • Si je suis installe des choses de la source sur un système qui est par ailleurs géré à l' aide des paquets, quelle est la manière la plus propre de le faire?
  • En supposant que je réussisse à compiler quelque chose de compliqué à partir de la source, comment puis-je le regrouper de manière à ce que les autres personnes ne soient pas obligées de sauter par les mêmes obstacles? Particulièrement sur OS X ....
  • Quels sont les outils de ligne de commande que je dois maîtriser pour réussir dans ce domaine? Des choses comme otool, pkg-config etc.

Je suis disposé à investir pas mal de temps et d'efforts ici - je ne veux pas nécessairement de réponses directes aux questions ci-dessus, je préférerais de loin recevoir des recommandations sur les livres / tutoriels / FAQ que je peux lire et qui me donneront la connaissances J'ai besoin de comprendre ce qui se passe réellement et donc de résoudre les problèmes par moi-même.

Simon Willison
la source

Réponses:

40

Je m'excuse d'avoir répondu directement à tout, mais je ne connais pas de tutoriels utiles, de FAQ, etc. Ce qui suit est essentiellement 8 années de création d'applications de bureau (que j'aide à distribuer), de frustration et de recherche sur Google:

1. Comment savoir quels arguments transmettre à ./configure?

Pratique vraiment. Autotools est assez facile car il est cohérent. Mais il y a beaucoup de choses là-bas utilisant cmake, ou des scripts de construction personnalisés. Généralement, vous ne devriez rien avoir à configurer, il faut savoir si votre système peut construire foo-tool ou non.

Les outils de configuration et GNU recherchent tous des dépendances dans /, / usr et / usr / local. Si vous installez quoi que ce soit ailleurs (ce qui rend les choses difficiles si la dépendance a été installée par MacPorts ou Fink), vous devrez passer un indicateur pour configurer ou modifier l'environnement du shell afin d'aider les outils GNU à trouver ces dépendances.

2. Comment fonctionnent les bibliothèques partagées sous OS X / Linux - où elles résident sur le système de fichiers, comment ./configure && les trouve, ce qui se passe réellement quand elles sont liées

Sous Linux, ils doivent être installés sur un chemin que l’éditeur de liens dynamique peut trouver, défini par la LD_LIBRARY_PATHvariable d’environnement et le contenu de /etc/ld.conf. Sur Mac, c'est presque toujours le même pour la plupart des logiciels open source (sauf s'il s'agit d'un projet Xcode). Sauf que la variable env est à la DYLD_LIBRARY_PATHplace.

Il existe un chemin d'accès par défaut dans lequel l'éditeur de liens recherche les bibliothèques. C'est / lib: / usr / lib: / usr / local / lib

Vous pouvez compléter cela en utilisant la variable CPATH, ou CFLAGS ou un nombre quelconque d'autres variables d'environnement (compliqué). Je suggère CFLAGS comme suit:

export CFLAGS = "$ CFLAGS -L / new / path"

Le paramètre -L ajoute au chemin du lien.

Les choses modernes utilisent l'outil pkg-config. Le matériel moderne que vous installez installe également un fichier .pc qui décrit la bibliothèque et son emplacement, ainsi que les liens correspondants. Cela peut rendre la vie plus facile. Mais il n’est pas fourni avec OS X 10.5, vous devrez donc également l’installer. De plus, beaucoup de bases ne le supportent pas.

Le fait de lier est simplement "résoudre cette fonction au moment de l'exécution", en réalité c'est une grande table de chaînes.

3. Quelles sont les différences réelles entre une bibliothèque partagée et une bibliothèque liée statiquement? Pourquoi ne puis-je pas tout lier de manière statique (la RAM et l’espace disque sont bon marché de nos jours) et éviter ainsi d’étranges conflits de versions de bibliothèques?

Lorsque vous créez un lien vers un fichier de bibliothèque statique, le code devient une partie de votre application. Ce serait comme s'il y avait un fichier .c géant pour cette bibliothèque et que vous l'aviez compilé dans votre application.

Les bibliothèques dynamiques ont le même code, mais lors de l'exécution de l'application, le code est chargé dans l'application au moment de l'exécution (explication simplifiée).

Vous pouvez relier statiquement à tout, mais malheureusement, pratiquement aucun système de construction ne facilite cela. Vous devez éditer manuellement les fichiers du système de construction (par exemple, Makefile.am ou CMakeLists.txt). Cependant, cela vaut probablement la peine d'apprendre si vous installez régulièrement des choses nécessitant différentes versions de bibliothèques et que vous rencontrez des difficultés pour installer des dépendances en parallèle.

L'astuce consiste à changer la ligne de liaison de -lfoo à -l / path / à / static / foo.a

Vous pouvez probablement trouver et remplacer. Ensuite, vérifiez que l’outil n’est pas lié au .so ou dylib avec ldd foo ou otool -L foo

Un autre problème est que toutes les bibliothèques ne compilent pas en bibliothèques statiques. Beaucoup le font. Mais alors, MacPorts ou Debian ont peut-être décidé de ne pas l'expédier.

4. Comment puis-je savoir quelles bibliothèques j'ai installées et quelles versions?

Si vous avez des fichiers pkg-config pour ces bibliothèques, rien de plus simple:

pkg-config --list-all

Sinon, vous ne pouvez souvent pas facilement. Le dylib peut avoir un soname (c'est-à-dire foo.0.1.dylib, le soname est égal à 0,1) qui est identique à la version de la bibliothèque. Cependant, ce n'est pas requis. Soname est une fonctionnalité de calcul binaire, vous devez modifier la majeure partie du soname si vous modifiez le format des fonctions de la bibliothèque. Ainsi, vous pouvez obtenir par exemple. version 14.0.5 soname pour une bibliothèque 2.0. Bien que ce ne soit pas commun.

Je suis frustré par ce genre de chose et j'ai développé une solution pour cela sur Mac, et j'en parle maintenant.

5. Comment puis-je installer plus d'une version d'une bibliothèque sans casser mon système normal?

Ma solution à ceci est ici: http://github.com/mxcl/homebrew/

J'aime installer depuis les sources et je voulais un outil qui facilite la tâche, mais avec une certaine gestion des paquets. Donc, avec Homebrew je construis, par exemple. moi-même depuis les sources, mais assurez-vous d'installer un préfixe spécial:

/usr/local/Cellar/wget/1.1.4

J'utilise ensuite l'outil homebrew pour créer un lien symbolique vers tout cela dans / usr / local. Il me reste donc toujours / usr / local / bin / wget et /usr/local/lib/libwget.dylib

Plus tard, si j’ai besoin d’une autre version de wget, je peux l’installer en parallèle et changer simplement la version liée à l’arborescence / usr / local.

6. Si j'installe des éléments à partir des sources sur un système géré autrement à l'aide de packages, quel est le moyen le plus simple de le faire?

Je crois que la manière Homebrew est la plus propre, alors utilisez-la ou faites l'équivalent. Installez dans / usr / local / pkgs / name / version et un lien symbolique ou un lien physique, le reste dans.

Utilisez / usr / local. Tous les outils de construction existants y recherchent des dépendances et des en-têtes. Votre vie sera beaucoup plus facile.

7. En supposant que je réussisse à compiler quelque chose de fâcheux à partir de la source, comment puis-je le regrouper afin que les autres personnes ne soient pas obligées de sauter par les mêmes obstacles? Particulièrement sur OS X ....

S'il ne comporte pas de dépendances, vous pouvez archiver le répertoire de construction et le donner à quelqu'un d'autre qui pourra ensuite faire "make install". Cependant, vous ne pouvez le faire que de manière fiable pour les mêmes versions exactes de OS X. Sous Linux, cela fonctionnera probablement pour des systèmes Linux similaires (par exemple Ubuntu) avec la même version du noyau et la version mineure de libc.

La raison pour laquelle il n'est pas facile de distribuer des fichiers binaires sous Unix est due à la compatibilité binaire. Les utilisateurs de GNU et tous les autres modifient souvent leurs interfaces binaires.

En gros, ne distribuez pas de fichiers binaires. Les choses vont probablement se briser de manière très étrange.

Sur Mac, la meilleure option consiste à créer un package macports. Tout le monde utilise macports. Sous Linux, il existe une multitude de systèmes de construction et de combinaisons différentes. Je ne pense pas qu'il soit préférable de rédiger une entrée de blog expliquant comment vous avez réussi à créer x tool dans une configuration étrange.

Si vous faites une description du paquet (pour macports ou homebrew), tout le monde peut l’installer, ce qui résout également les problèmes de dépendance. Cependant, ce n'est souvent pas facile, et il n'est pas facile non plus que votre recette de macports soit incluse dans l'arbre principal de macports. De plus, macports ne supporte pas les types d'installation exotiques, ils offrent un choix pour tous les paquets.

Un de mes objectifs futurs avec Homebrew est de permettre de cliquer sur un lien sur un site Web (par exemple, homebrew: // blah et il téléchargera ce script Ruby, installera les dépôts de ce paquet, puis construira l’application. Mais oui, pas encore fait, mais pas trop délicat compte tenu du design que j'ai choisi.

8. Quels sont les outils en ligne de commande que je dois maîtriser pour réussir dans ce domaine? Des choses comme otool, pkg-config etc.

otool n'est vraiment utile qu'après. Il vous indique les liens binaires construits. Lorsque vous déterminez les dépendances d'un outil que vous devez construire, cela ne sert à rien. Il en va de même pour pkg-config car vous aurez déjà installé la dépendance avant de pouvoir l'utiliser.

Ma chaîne d’outils est de lire les fichiers README et INSTALL, puis de configurer --help. Regardez la sortie pour vérifier si elle est saine d’esprit. Analyser toutes les erreurs de construction. Peut-être qu'à l'avenir, demandez à serverfault :)

Max Howell
la source
2
Intéressant, Homebrew ressemble beaucoup à Portage (le gestionnaire de paquets de Gentoo Linux). Cela ressemble à un beau travail.
David Z
12

Il s’agit d’un sujet important. Commençons par les bibliothèques partagées sous Linux (ELF sous Linux et Mach-O sous OS X). Ulrich Drepper a une bonne introduction à l’écriture de DSO (objets partagés dynamiques) qui couvre une partie de l’historique des bibliothèques partagées sous Linux. ici, y compris pourquoi ils sont importants

Ulrich explique également pourquoi les liens statiques sont considérés comme préjudiciables . Les mises à jour de sécurité constituent l’un des points clés. Les débordements de mémoire tampon dans une bibliothèque commune (par exemple, zlib) très liée statiquement peuvent entraîner une surcharge considérable pour les distributions - ceci se produit avec zlib 1.1.3 (Avis Red Hat )

ELFE

La page de manuel de l'éditeur de liens ld.so

man ld.so 

explique les chemins et les fichiers de base impliqués dans la liaison dynamique au moment de l'exécution. Sur les systèmes Linux modernes, des chemins supplémentaires sont ajoutés via /etc/ld.so.conf.d/ généralement ajoutés via un glob include dans /etc/ld.so.conf.

Si vous voulez voir ce qui est disponible dynamiquement via votre configuration ld.so, vous pouvez exécuter

ldconfig -v -N -X

La lecture du manuel d'utilisation DSO devrait vous fournir un bon niveau de connaissances de base pour que vous puissiez ensuite comprendre comment ces principes s'appliquent à Mach-O sous OS X.

Mach-O

Sous OS X, le format binaire est Mach-O. La documentation système locale de l'éditeur de liens est

man dyld

La documentation au format Mach est disponible chez Apple.

Outils de compilation UNIX

La commune configure, make, make installprocessus est généralement fourni par GNU autotools qui a un livre en ligne qui couvre une partie de l'histoire de la configuration / build Split et la GNU toolchain. Autoconf utilise des tests pour déterminer la disponibilité des fonctionnalités sur le système de génération cible. Pour ce faire, il utilise le langage macro M4 . Automake est fondamentalement une méthode de création de modèles pour Makefiles, le modèle étant généralement appelé Makefile.am qui génère un Makefile.in que la sortie de autoconf (le script configure) convertit en un Makefile.

Le programme GNU hello est un bon exemple pour comprendre la chaîne d’outils GNU - et le manuel inclut la documentation d’autotools.


la source
10

Simon! Je sais ce que tu ressens; J'ai également eu du mal avec cette partie de l'apprentissage de Linux. Sur la base de mes propres expériences, j'ai écrit un didacticiel sur certains des éléments que vous abordez (principalement à titre de référence!): Http://easyaspy.blogspot.com/2008/12/buildinginstalling-application-from.html . Je pense que vous apprécierez ma remarque sur la simplicité de la création / installation d'applications Python. :)

J'espère que ça aide! Et bonne compilation.

Tim Jones


Construire / Installer une application à partir du source dans Ubuntu Linux

Alors que les dépôts Ubuntu regorgent d’applications géniales, vous rencontrerez à un moment ou à un autre cet outil "indispensable" qui ne figure pas dans les dépôts (ou qui n’a pas de paquet Debian) ou vous avez besoin d’un version plus récente que dans les référentiels. Que faire? Eh bien, vous devez créer l’application à partir des sources! Ne vous inquiétez pas, ce n'est vraiment pas aussi compliqué que ça en a l'air. Voici quelques conseils, tirés de mon expérience d’amateur de rang! (Bien que j'utilise Ubuntu pour cet exemple, les concepts généraux devraient être applicables à la plupart des distributions Unix / Linux, telles que Fedora, et même à la plate-forme Cygwin sous Windows.)

Le processus de base de la construction (compilation) de la plupart des applications à partir des sources suit cette séquence: configure -> compiler -> install. Les commandes Unix / Linux typiques pour faire ces choses sont: config-> make-> make install. Dans certains cas, vous trouverez même des pages Web qui montrent que toutes ces choses peuvent être combinées en une seule commande:

$ config && make && make install

Bien entendu, cette commande suppose qu'il n'y a pas de problèmes dans aucune de ces étapes. C'est là que le plaisir entre en jeu!

Commencer

Si vous n'avez jamais compilé une application à partir des sources sur votre système, vous devrez probablement la configurer avec des outils de développement généraux, tels que la gccsuite du compilateur, des fichiers d'en-tête courants (considérez cela comme du code déjà écrit par quelqu'un d'autre utilisé par le programme que vous installez) et l'outil make. Heureusement, dans Ubuntu, il existe un métapaquet appelé build-essentialqui va installer cela. Pour l'installer (ou juste vous assurer que vous l'avez déjà!), Lancez cette commande dans le terminal:

$ sudo apt-get install build-essential

Maintenant que vous avez la configuration de base, téléchargez les fichiers source de l'application et enregistrez-les dans un répertoire pour lequel vous disposez d'autorisations de lecture / écriture, tel que votre répertoire "home". Généralement, ils seront dans un fichier d’archive avec l’extension de fichier .tar.gzou .tar.bz2. Le .tarsignifie simplement qu'il est une « bande d' archive », qui est un regroupement de fichiers qui préserve leur structure de répertoire relatif. Le .gzsigle signifie gzip (GNU zip), qui est un format de compression populaire Unix / Linux. De même, le .bz2sigle de bzip2, qui est un nouveau format de compression offrant une compression plus élevée (taille de fichier compressée plus petite) que gzip.

Après avoir téléchargé le fichier source, ouvrez une fenêtre de terminal (Terminal système dans le menu Ubuntu) et accédez au répertoire dans lequel vous avez enregistré votre fichier. (Je vais utiliser ~/downloaddans cet exemple. Ici, '~' est un raccourci vers votre répertoire "home".) Utilisez la commande tar pour extraire les fichiers du fichier archive téléchargé:

Si votre fichier est une archive gzip (par exemple, se termine par .tar.gz), utilisez la commande suivante:

            $ tar -zxvf filename.tar.gz

Si votre fichier est une archive bzip2 (se termine par exemple .tar.bz2), utilisez la commande suivante:

            $ tar -jxvf filename.tar.gz

Conseil: Si vous ne voulez pas vous souvenir de tous les commutateurs de ligne de commande pour extraire des archives, je vous recommande d’obtenir l’un (ou les deux) utilitaires suivants: dtrx (mon préféré!) Ou déco (plus populaire). Avec l’un ou l’autre de ces utilitaires, il vous suffit de saisir le nom de l’utilitaire (dtrx ou deco) et le nom du fichier, c’est lui qui fait le reste. Ces deux "savent" comment gérer la plupart des formats d'archives que vous êtes susceptible de rencontrer et ils ont une excellente gestion des erreurs.

Lors de la création à partir des sources, il existe deux types d’erreurs que vous êtes susceptible de rencontrer:

  1. Des erreurs de configuration se produisent lorsque vous exécutez le script de configuration (généralement nommé config ou configure) pour créer un fichier make spécifique à votre configuration.
  2. Les erreurs du compilateur surviennent lorsque vous exécutez la commande make (après la génération du fichier makefile) et que le compilateur est incapable de trouver le code dont il a besoin.

Nous examinerons chacune d’elles et discuterons de la façon de les résoudre.

Configuration et erreurs de configuration

Une fois que vous avez extrait le fichier d’archive de code source, dans le terminal, vous devez passer au répertoire contenant les fichiers extraits. En règle générale, ce nom de répertoire sera le même que le nom du fichier (sans l' extension .tar.gzou .tar.bz2). Cependant, le nom du répertoire n'est parfois que le nom de l'application, sans aucune information de version.

Dans le répertoire source, recherchez un READMEfichier et / ou un INSTALLfichier (ou un nom similaire). Ces fichiers contiennent généralement des informations utiles sur la manière de construire / compiler l'application et de l'installer, y compris des informations sur les dépendances. "Dépendances" ne sont qu'un nom de fantaisie pour d'autres composants ou bibliothèques nécessaires à la compilation.

Une fois que vous avez lu le fichier READMEet / ou le INSTALLfichier (et, espérons-le, examiné toute documentation en ligne pertinente pour l'application), recherchez un fichier exécutable (le jeu d'autorisations "x" figurant sur le fichier) est nommé configou configure. Parfois, le fichier peut avoir une extension, telle que .sh(par exemple, config.sh). Il s'agit généralement d'un script shell qui exécute d'autres utilitaires pour confirmer que vous disposez d'un environnement "sain" pour la compilation. En d’autres termes, il vérifiera que vous avez installé tout ce dont vous avez besoin.

Conseil: S'il s'agit d'une application basée sur Python, à la place d'un fichier de configuration, vous devriez trouver un fichier nommé setup.py. Les applications Python sont généralement très simples à installer. Pour installer cette application en tant que root (par exemple, mettez sudo devant la commande suivante sous Ubuntu), exécutez cette commande:

    $ python setup.py install

Cela devrait être tout ce que vous devez faire. Vous pouvez ignorer le reste de ce didacticiel et passer directement à l'utilisation de votre application et à son utilisation.

Exécutez le script de configuration dans le terminal. En règle générale, vous pouvez (et devriez!) Exécuter votre script de configuration avec votre compte utilisateur habituel.

$ ./config

Le script affichera quelques messages pour vous donner une idée de ce qu’il fait. Souvent, le script vous indique s'il a réussi ou non et, en cas d'échec, des informations sur la cause de l'échec. Si vous ne recevez aucun message d'erreur, vous pouvez généralement supposer que tout s'est bien passé.

Si vous ne trouvez aucun script ressemblant à un script de configuration, cela signifie généralement que l'application est très simple et qu'elle est indépendante de la plate-forme. Cela signifie que vous pouvez simplement passer à l'étape de construction / compilation ci-dessous, car l'option fournie Makefiledevrait fonctionner sur n'importe quel système.

Un exemple

Dans ce tutoriel, je vais utiliser le lecteur RSS à base de texte appelé Newsbeuter comme exemple des types d’erreurs que vous pouvez rencontrer lors de la création de votre application. Pour Newsbeuter, le nom du script de configuration est config.sh. Sur mon système, lorsque j'exécute config.sh, les erreurs suivantes se produisent:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ ./config.sh
Checking for package sqlite3... not found

You need package sqlite3 in order to compile this program.
Please make sure it is installed.

Après quelques recherches, j'ai découvert qu'en fait, l' sqlite3application était installée. Cependant, étant donné que j'essaie de compiler à partir des sources, il s'agit d'un conseil qui config.shrecherche réellement les bibliothèques de développement (en-têtes) sqlite3. Dans Ubuntu, la plupart des paquets ont un paquet de développement associé qui se termine par -dev. (D'autres plates-formes, telles que Fedora, utilisent souvent un suffixe de package -develpour les packages de développement.)

Pour trouver le paquet approprié pour le sqlite3paquet de développement, nous pouvons utiliser l' apt-cacheutilitaire dans Ubuntu (et, de la même manière, l' yumutilitaire dans Fedora):

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-cache search sqlite

Cette commande retourne une assez longue liste de résultats, nous devons donc faire un peu de travail de détective pour déterminer quel est le paquet approprié. Dans ce cas, le package approprié s'avère être libsqlite3-dev. Notez que parfois le paquet que nous recherchons aura le libpréfixe, au lieu du même nom de paquet plus -dev. En effet, nous cherchons parfois une bibliothèque partagée pouvant être utilisée par de nombreuses applications différentes. Pour l'installer libsqlite3-dev, lancez la commande typique apt-get install dans le terminal:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-get install libsqlite3-dev

Maintenant, nous devons réexécuter config.shpour nous assurer que nous avons résolu ce problème de dépendance et que nous n’avons plus de problèmes de dépendance. (Bien que je ne le montre pas ici, dans le cas de Newsbeuter, je devais également installer le libcurl4-openssl-devpackage également.) De plus, si vous installez un package de développement (du type libsqlite3-dev) et que le package d'application associé (par exemple, sqlite3) n'est pas déjà installé, la plupart des systèmes installent automatiquement le package d’application associé au même moment.

Lorsque la configuration est exécutée avec succès, le résultat sera que cela créera un ou plusieurs fichiers make. Ces fichiers sont généralement nommés Makefile(rappelez-vous que la casse du nom de fichier est importante dans Unix / Linux!). Si le package de construction comprend des sous-répertoires, tels que src, etc., chacun de ces sous-répertoires contiendra également un Makefile,.

Erreurs de construction et de compilation

Nous sommes maintenant prêts à compiler l'application. Cela s'appelle souvent bâtiment et son nom est emprunté au processus réel de construction de quelque chose. Les différentes "parties" de l'application, qui sont généralement plusieurs fichiers de code source, sont combinées pour former l'ensemble de l'application. L'utilitaire make gère le processus de construction et appelle d'autres applications, telles que le compilateur et l'éditeur de liens, pour effectuer le travail. Dans la plupart des cas, vous exécutez simplement make (avec votre compte utilisateur habituel) à partir du répertoire dans lequel vous avez exécuté la configuration. (Dans certains cas, tels que la compilation d'applications écrites avec la bibliothèque Qt, vous devrez exécuter une autre application "wrapper" comme qmake. Encore une fois, vérifiez toujours les documents READMEet / ou INSTALLpour plus de détails.)

Comme avec le script de configuration ci-dessus, lorsque vous exécutez make (ou un utilitaire similaire) sur le terminal, des messages concernant ce qui est en cours d'exécution ainsi que les avertissements et les erreurs s'affichent. Vous pouvez généralement ignorer les avertissements, car ils sont principalement destinés aux développeurs de l'application et leur indiquent qu'il existe certaines pratiques standard enfreintes. Généralement, ces avertissements n’affectent pas la fonction de l’application. D'autre part, les erreurs du compilateur doivent être traitées. Avec Newsbeuter, quand j'ai exécuté make, tout s'est bien passé pendant un moment, mais j'ai eu une erreur:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ make
...
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/configparser.o -c src/configparser.cpp
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/colormanager.o -c src/colormanager.cpp
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:5:18: error: stfl.h: No such file or directory
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:33: error: ISO C++ forbids declaration of \u2018stfl_form\u2019 with no type
./include/stflpp.h:33: error: expected \u2018;\u2019 before \u2018*\u2019 token
./include/stflpp.h:34: error: ISO C++ forbids declaration of \u2018stfl_ipool\u2019 with no type
./include/stflpp.h:34: error: expected \u2018;\u2019 before \u2018*\u2019 token
make: *** [src/colormanager.o] Error 1

Le processus de création s’arrête dès que la première erreur est rencontrée. La gestion des erreurs du compilateur peut parfois s'avérer délicate. Vous devez regarder les erreurs pour trouver des indices sur le problème. Généralement, le problème est que certains fichiers d’en-tête, qui portent généralement l’extension .hou .hpp, sont manquants. Dans le cas de l'erreur ci-dessus, il est (ou devrait être!) Clair que le problème est que le stfl.hfichier d'en-tête est introuvable. Comme le montre cet exemple, vous souhaitez consulter les premières lignes du message d'erreur et rechercher la cause sous-jacente du problème.

Après avoir examiné la documentation de Newsbeuter (ce que j'aurais dû faire avant de commencer, mais cette partie du didacticiel n'aurait pas beaucoup de sens!), J'ai constaté qu'elle nécessite une bibliothèque tierce appelée STFL. Alors, que faisons-nous dans ce cas? Eh bien, nous répétons essentiellement le même processus pour la bibliothèque requise: obtenez la bibliothèque et exécutez le processus configure-build-install correspondant, puis reprenez la construction de l’application souhaitée. Par exemple, dans le cas de STFL, je devais installer le libncursesw5-devpackage pour pouvoir le construire correctement. (Habituellement, il n'est pas nécessaire de refaire l'étape de configuration sur notre application d'origine après avoir installé une autre application requise, mais cela ne fait jamais de mal non plus.)

Une fois la boîte à outils STFL installée avec succès, le processus de création de Newsbeuter s’est déroulé avec succès. Le processus de création est généralement repris là où il se termine (au moment de l'erreur). Ainsi, tous les fichiers ayant déjà été compilés avec succès ne seront pas recompilés. Si vous voulez tout recompiler, vous pouvez exécuter make clean all pour supprimer tous les objets compilés, puis réexécuter make.

L'installation

Une fois le processus de génération terminé, vous êtes prêt à installer l'application. Dans la plupart des cas, pour installer l'application sur les zones communes du système de fichiers (par exemple, /usr/binou /usr/share/bin, etc.), vous devez exécuter l'installation en tant que root. L'installation est vraiment l'étape la plus simple de tout le processus. Pour installer, dans le terminal, exécutez:

$ make install

Vérifiez la sortie de ce processus pour toutes les erreurs. Si tout a réussi, vous devriez pouvoir exécuter le nom de la commande dans le terminal et le lancer. (Ajoutez & à la fin de la ligne de commande, s'il s'agit d'une application graphique, ou vous ne pourrez pas utiliser la session de terminal tant que l'application ne sera pas lancée.)

Lorsque vous construisez une application à partir des sources, il n’est généralement pas ajouté d’icône ou de raccourci aux menus de l’interface graphique d’Ubuntu. Vous devrez ajouter ceci manuellement.

Et c’est essentiellement le processus, bien que potentiellement itératif, permettant de créer et d’installer une application à partir de la source dans Ubuntu. Après avoir fait cela à quelques reprises, cela deviendra une seconde nature pour vous!

Tim Jones
la source
Tim, j'aurais bien aimé lire votre tutoriel, mais le lien que vous avez posté ne fonctionne pas.
gareth_bowles
6

Eh bien, ./configure --help vous donnera beaucoup d’informations sur les fichiers de configuration générés par les outils automatiques GNU. La plupart de cela revient à --with / - sans activer les fonctionnalités (celles-ci peuvent prendre un paramètre supplémentaire, comme "shared" pour dire où trouver la bibliothèque).

Les autres plus importants sont --prefix (qui utilise par défaut / usr / local / la plupart du temps) pour dire où installer (si vous construisez des paquets, vous voulez généralement ceci comme --prefix = / usr ou peut-être --prefix = / opt / YourPackage).

Sous Linux, les fichiers / lib, / usr / lib et / usr / local / lib sont généralement interrogés dans mon gcc et inclus dans la configuration par défaut de ldconfig. À moins que vous n’ayez une bonne raison, c’est là que vous voulez vos bibliothèques. /etc/ld.so.conf peut cependant lister des entrées supplémentaires.

configurez et faites les trouver simplement en essayant d’exécuter "gcc -l" et en vérifiant s’il s’agit d’une erreur Vous pouvez ajouter "-L" à votre paramètre CFLAGS pour ajouter des chemins supplémentaires à la recherche.

Vous pouvez avoir plusieurs versions installées, et les logiciels liés à une ancienne version resteront liés (lancez ldd pour trouver la liaison sous Linux), mais les nouvelles compilations ciblent généralement la dernière version d'une bibliothèque dynamique sur votre système.

La plupart des logiciels supposent des bibliothèques dynamiques, en particulier si elles utilisent libtool. Par conséquent, il est possible que des applications non triviales ne se construisent pas correctement de manière statique.

ls -l est votre meilleur choix pour trouver les bibliothèques installées.

Et c'est là que je suis à court d'informations. comment bien jouer avec les paquets: je ne sais pas. Lorsque cela est possible, j'essaie de regrouper les éléments dans un package pour éviter le problème.

Aaron Brady
la source
4

"Comment puis-je savoir quels arguments transmettre à ./configure?"

généralement: ./configure --help vous dira ce que vous voulez là.

"Comment puis-je savoir quelles bibliothèques j'ai installées et quelles versions?"

Cela dépend du système. Une solution consiste simplement à faire en sorte find /|grep libname|lessque les fichiers de bibliothèque aient généralement la version dans le nom du fichier.

"Comment puis-je installer plus d'une version d'une bibliothèque sans casser mon système normal?"

Encore une fois, cela dépend du système et de la bibliothèque. sudo make altinstallcréera un nom versionné pour vous. Les fichiers de bibliothèque ont généralement la version eux-mêmes. Gardez à l'esprit cependant; étant donné que les versions créent souvent des liens symboliques vers un nom "normalisé", cela peut casser des choses.

"Si j'installe des éléments à partir des sources sur un système autrement géré à l'aide de packages, quel est le moyen le plus propre de le faire?"

Utiliser les paramètres --prefix dans ./configure et les placer quelque part /optest une bonne pratique à suivre.

Disclaimer: Je ne suis en aucun cas un expert, mais j'utilise Linux depuis plus de 5 ans à partir de la ligne de commande (slackware, CentOS, RedHat, Ubuntu, divers autres et OS X).

Phillip B Oldham
la source
4

Pour répondre à un peu de votre question, j’ai trouvé l’autre jour un bon moyen de voir quelles bibliothèques vous avez installées et quelles versions (cela concerne Linux Debian, donc cela fonctionnera aussi avec d’autres versions).

dpkg --list

Vous devriez avoir une très longue liste avec des sorties comme celle-ci

ii  libssl0.9.8    0.9.8c-4etch5  SSL shared libraries
ii  libssp0        4.1.1-21       GCC stack smashing protection library
ii  libstdc++5     3.3.6-15       The GNU Standard C++ Library v3
ii  libstdc++5-3.3 3.3.6-15       The GNU Standard C++ Library v3 (development
ii  libstdc++6     4.1.1-21       The GNU Standard C++ Library v3
Mark Davidson
la source
4

Simon,

1.) ./configure --help fournit une bonne quantité d’informations. Je suggère de vérifier. Il a généralement des options pour compiler des bibliothèques liées statiquement / dynamiquement, le cas échéant.

2.) Les bibliothèques résident dans le chemin de l’éditeur de liens dynamique. Ceci est généralement défini dans /etc/ld.so.conf. L'éditeur de liens recherche les bibliothèques appropriées un peu comme la variable d'environnement PATH correspondant à la première trouvée.

3.) Cela pose généralement des problèmes car vous devez tout recompiler quand une version de bibliothèque change. Si vous effectuez des recherches, vous découvrirez probablement une foule de raisons pour lesquelles la liaison statique est une mauvaise idée. Je ne l'ai pas fait depuis si longtemps que je ne peux pas vraiment élaborer ici.

4.) C'est un peu difficile. Vous devez vérifier le chemin de votre bibliothèque pour vous en assurer. Les bibliothèques ont généralement un lien symbolique vers la version installée.

par exemple, libssh2.so.1 -> libssh2.so.1.0.0

Généralement, les gens gèrent les bibliothèques et les programmes qu’ils installent en lançant leurs propres paquets Debian ou en utilisant une autre technique. Je gère le logiciel installé à l'aide de stow ( http://www.gnu.org/software/stow/ ), ce qui est très simple et installe la bibliothèque à l'aide de liens symboliques. Je trouve cela plus facile car je n'ai pas à construire / installer / tester un paquet deb / rpm.

5.) Plusieurs versions de bibliothèques peuvent être installées normalement dans les répertoires de bibliothèques. Les bibliothèques liées aux exécutables resteront liées aux versions auxquelles elles étaient liées. exécuter ldd sur un exécutable vous indiquera à quelles bibliothèques l’exécutable est lié.

6.) Comme je l'ai mentionné précédemment, faire rouler vos propres paquets Debian ou utiliser stow est probablement la solution la plus propre.

7.) Je ne peux pas vraiment parler pour Mac OSX, mais pour Linux, le système de conditionnement de la distribution est le meilleur moyen.

8.) Il est probable que beaucoup de frustrations seront résolues en utilisant ldd et en recherchant la version avec laquelle quelque chose est lié ou la bibliothèque liée à un exécutable introuvable. pkg-config vous aidera beaucoup, mais uniquement pour les logiciels qui l'utilisent. Cela ne fait pas partie du système de construction par défaut des outils automatiques, bien qu'il soit populaire de nos jours.

Ian Lewis
la source
4

Les bibliothèques statiques ne sont pas une bonne idée. Si vous devez mettre à niveau la bibliothèque (pour résoudre un problème de sécurité, par exemple), vous devez tout recompiler avec une dépendance à cette bibliothèque.

Je n'aime pas l'idée de "make install" qui risque de perturber mon système, mais comme d'autres l'ont déjà dit, il est généralement beaucoup moins pénible d'installer des éléments dans / usr / local au lieu d'utiliser --prefix pour installer ailleurs. Donc, j’ai chonné / usr / local à mon utilisateur habituel (non privilégié). De cette façon, "make install" est quasiment garanti pour ne pas gâcher les fichiers système importants. (Cela ne fonctionnera évidemment pas sur les systèmes multi-utilisateurs. C'est excellent pour les serveurs virtuels, cependant.)

ithinkihaveacat
la source
4

Bien que cela ne soit pas explicitement dans votre liste de questions, vous mentionnez dans votre préface:

./configure && make && sudo make install est généralement suffisant, mais parfois cela ne fonctionne pas - et quand cela ne fonctionne pas, je suis souvent coincé.

Lorsque je suis bloqué sur Debian ou Ubuntu, je vais utiliser auto-apt qui installera automatiquement les paquets contenant les fichiers que configure ne peut pas trouver.

Voir:

CheckInstall est un autre outil qui peut vous être utile. Il ajoute des applications installées make installà votre liste de packages installés: https://help.ubuntu.com/community/CheckInstall.

Swoogan
la source
3

Pour OS X:

  • Comment déterminer quels arguments transmettre à ./configure?

./configure --help

  • Quelles sont les différences réelles entre une bibliothèque partagée et une bibliothèque liée statiquement? Pourquoi ne puis-je pas tout lier de manière statique (la RAM et l’espace disque sont bon marché de nos jours) et éviter ainsi d’étranges conflits de versions de bibliothèques?

L'utilisation de bibliothèques partagées vous permet de mettre à niveau la bibliothèque sans recompiler tout ce qui en fait usage.

  • Fonctionnement des bibliothèques partagées sous OS X / Linux - leur emplacement sur le système de fichiers, la manière dont ./configure && les trouve

Les bibliothèques système résident dans / usr / lib.

Les bibliothèques que vous vous compilez vivent dans / usr / local / lib (/ usr / local étant l'indicateur par défaut --prefix pour ./configure).

Les variables d'environnement DYLD_FALLBACK_LIBRARY_PATH et LD_LIBRARY_PATH vous permettent de spécifier les dossiers dans lesquels rechercher, de sorte que / usr / local / lib doit figurer au début de la liste.

  • Comment puis-je installer plus d'une version d'une bibliothèque sans casser mon système normal?

Tout installer dans / usr / local - avec les variables d’environnement ci-dessus, la version dans / usr / local / lib est prioritaire sur la version dans / usr / lib de votre environnement.

  • Si j'installe des éléments à partir des sources sur un système autrement géré à l'aide de packages, quel est le moyen le plus simple de le faire?

Installez dans / usr / local. Dans Ubuntu, j’essaie d’utiliser d’abord checkinstall pour créer un paquet deb.

  • En supposant que je réussisse à compiler quelque chose de compliqué à partir de la source, comment puis-je le regrouper de manière à ce que les autres personnes ne soient pas obligées de sauter par les mêmes obstacles? Particulièrement sur OS X ....

Documentez les étapes de la compilation dans un article de blog, je dirais.

Alf Eaton
la source