Compiler un binaire statique qui code une fonction gethostbyname
Comment résoudre compiler un binaire statique qui code une fonction gethostbyname et si compilé sans avertissement comme ceci:
avertissement: à l'Aide de "gethostbyname" dans les applications liées statiquement
nécessite au runtime des bibliothèques partagées à partir de la version de la glibc utilisé
pour relier
Je compile sur ubuntu 12.04 avec la commande:
$ gcc -static lookup.c -o lookup
C'est le code pour la recherche.c:
/* lookup.c */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
extern int h_errno;
int main(int argc,char **argv) {
int x, x2;
struct hostent *hp;
for ( x=1; x<argc; ++x ) {
hp = gethostbyname(argv[x]);
if ( !hp ) {
fprintf(stderr,
"%s: host '%s'\n",
hstrerror(h_errno),
argv[x]);
continue;
}
printf("Host %s : \n" ,argv[x]);
printf(" Officially:\t%s\n", hp->h_name);
fputs(" Aliases:\t",stdout);
for ( x2=0; hp->h_aliases[x2]; ++x2 ) {
if ( x2 ) {
fputs(", ",stdout);
}
fputs(hp->h_aliases[x2],stdout);
}
fputc('\n',stdout);
printf(" Type:\t\t%s\n",
hp->h_addrtype == AF_INET
? "AF_INET" : "AF_INET6");
if ( hp->h_addrtype == AF_INET ) {
for ( x2=0; hp->h_addr_list[x2]; ++x2 ) {
printf(" Address:\t%s\n",
inet_ntoa( *(struct in_addr *)
hp->h_addr_list[x2]));
}
}
putchar('\n');
}
return 0;
}
Je veux si je vérifie via $ file lookup
obtiendrez de sortie comme ceci:
de recherche: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux),
statiquement, pour GNU/Linux 2.6.24,
BuildID[sha1]=0x6fcb2684ad8e5e842036936abb50911cdde47c73, non dénuée
Pas comme cela:
de recherche: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
liée de façon dynamique (utilise shared libs), pour GNU/Linux 2.6.24,
BuildID[sha1]=0xf9f18671751927bea80de676d207664abfdcf5dc, non dénuée
Si vous commentée avec a suggéré que je doit utiliser sans statique, parce que les différents libc tous les linux, je le savais, j'espère que vous n'avez pas besoin de commentaire.
Pourquoi dois-je rester statique?
Parce que là, j'ai besoin de faire afin de rendre obligatoire l'utilisation de la statique, des fichiers binaires doivent être statiques et non dynamiques.
J'ai plus que 2 semaines à la recherche pour cela, mais jusqu'à présent n'ont pas réussi.
Merci de m'aider à résoudre mon lourd problème.
libc.so
Bonjour Basile. Pourquoi?
Comment faire? qu'est-ce avec -Bdynamic -lc -Wl ?
BorealId réponse expliqué. Fondamentalement
/etc/nsswitch.conf
utilise dlopen
pour gethostbyname
donc besoin d'un programme lié dynamiquement (parce que l'éditeur de liens dynamique doit être là). Juste compiler avec gcc -Wall -g -O lookup.c -o lookup
et votre lookup
seront liés de façon dynamique.Si vous passez à un autre de la libc, pourquoi ne pas simplement utiliser le Android NDK pour compiler vos applications ? C'est ce que vous êtes censé faire, et qui vous donnera la bionique de la LIBC, et tout le reste vous avez besoin pour compiler des programmes qui s'exécutent sur android.
OriginalL'auteur Loren Ramly | 2013-03-01
Vous devez vous connecter pour publier un commentaire.
Ce que vous demandez est va être très difficile.
Voir cette question sur StackOverflow getaddrinfo. En gros, en dessous de
getaddrinfo
/gethostbyname
est de glibc NSS couche. Cela permet à un administrateur de dire "utiliser le DNS pour résoudre les noms d'hôtes en adresses IP", ou "l'utilisation du protocole LDAP", ou "ne pas utiliser autre chose que de/etc/hosts
". Ce contrôle est au moment de l'exécution; l'administrateur peut à tout moment changer la façon dont les noms d'hôtes sont résolus à IPs.En raison de cette flexibilité, l'ensemble de la résolution de noms d'appels dans la glibc, utiliser les bibliothèques d'assistance (plugins, essentiellement) pour faire la basse besogne de résolution. Il y a une bibliothèque partagée pour le LDAP de l'adressage, l'un pour les fichiers, un pour les DNS, un pour YP, et ainsi de suite et ainsi de suite.
Si vous voulez que votre programme pour être à 100% lié statiquement, vous allez avoir à aller ailleurs (PAS
gethostbyname
) pour convertir un nom d'hôte à une adresse IP. Vous pouvez le faire avec une bibliothèque de solutions comme uDNS (pas exactement celui - là sont des outils similaires disponibles), mais vous devez garder à l'esprit que votre binaire ne va pas faire la bonne chose sur les systèmes qui sont configurés pour ne pas utiliser le DNS!Au lieu de cela, je vous recommande juste de quitter le programme (techniquement) liés de façon dynamique. Si vraiment vous voulez vous assurer qu'il fonctionnera sur n'importe quelle plate-forme, vous pourriez même navire
glibc
avec le binaire - bien que cela nécessite LGPL conformité. En laissant ce un lien dynamique en place signifie seulement que vous ne fonctionne pas sur les systèmes avec le mauvaisglibc
version - n'est pas un énorme problème de compatibilité.Parlant de la conformité des licences, il est intéressant de noter que si vous lier statiquement
glibc
, vous plus susceptibles d'avoir à expédier le code source de votre ensemble de l'application pour se conformer à laglibc
's licence LGPL. Je ne suis pas un avocat, et ce n'est pas un conseil juridique, mais la lecture de la LGPL est très clair que les applications de la liaison statiqueglibc
doit être open-source. Voir cette StackOverflow question sur le sujet.+1 pour le permis de rappeler à propos de la LGPL dans la libc. Notez que certains libc-s ne sont pas LGPL, mais MIT par exemple musl-libc.org
Résolu avec musl-libc. Je compile mul-libc puis-je compiler mon programme, utiliser des bibliothèques musl-libc avec la commande -L/chemin/tomuslcompiled/lib . Je suis very2 heureux, Merci M. Borealid
que faites-vous pour gethostbyname() ? Avez-vous dlopen/dlsym de la glibc?
Pas besoin de dlopen/dlsym. musl comprend une mise en œuvre de gethostbyname() qui n'a pas besoin de la glibc helper plugins. Regardez ici - git.musl-libc.org/cgit/musl/tree/src/network
OriginalL'auteur Borealid
Je reçois le message d'avertissement et de le fixer j'ai recompilé la glibc. Allumez l'interrupteur
--enable-static-nss
lors de la configuration de l'obtenir pour fonctionner.OriginalL'auteur kimi shi
J'ai 2 réponses -
Garder la partie principale de votre programme lié statiquement, et de la distinguer d'une simple fonction du programme de simplement appeler gethostbyname(). Permettre à cette dernière d'être liée de manière dynamique. L'aide d'une fourchette puis exec exécuter ce programme distinct pour obtenir l'adresse d'un nom de domaine. Au lieu de fourchette puis exec vous pouvez utiliser system (), même si cela prend plus de temps (millisecondes) qui ne doivent pas être source d'inquiétude depuis que vous êtes à la recherche de serveurs de noms de domaine sur l'internet de toute façon, ce qui prend beaucoup de temps.
Écrire le code source pour faire le DNS, comme je l'ai fait. Compiler dans une archive (.un) et l'ont cherché dans la liaison statique.
OriginalL'auteur Clive