1

j'ai un problème à priori idiot.

un projet codeblocks, une application compilée avec mingw, elle est liée à ws2_32 (winsock2)

pas de souci jusque là, c'est bateau.

je mets le code réutilisable dans une lib statique (libmachin.a), qui référence ces fonctions winsock, mais je ne lie PAS cette lib avec winsock.
je mets le main.c dans un autre projet, que je linke avec libmachin.a ET ws2_32.

Et là, il arrive plus à linker a winsock. J'ai des tonnes de:

libmachin.a(daemon.o): In function `do_internal_command':
daemon.c:120: undefined reference to `closesocket@4'
libmachin.a(daemon.o): In function `daemon_init':
daemon.c:186: undefined reference to `WSAStartup@8'
libmachin.a(listener.o): In function `listener_create':
listener.c:41: undefined reference to `getaddrinfo@16'
listener.c:63: undefined reference to `freeaddrinfo@4'

etc etc etc

Donc, il est impossible de reloger des fonctions __stdcall qui sont appelées depuis une lib statique? trifus

je sais pas quoi googler pour trouver des solutions. J'ai essayé plein de trucs, totalement à coté de la plaque.


2

T'as posté sur leur forum pour demander comment linker ça bien ? Si ça tombe, tu dois compiler je ne sais comment ta lib statique pour que ça marche.

3

oui mais ou justement? grin

sur une mailing list mingw? sur une des multiples listes gcc? celle de binutils? grin
ça concerne pas codeblocks smile

je sèche là grin

j'ai essayé -fPIC sans succès:

warning: -fPIC ignored for target (all code is position independent)

4

putain j'ai trouvé

c'est l'ordre

gcc.exe -L..\DaemonBase\bin\Debug\ -LC:\MinGW\gcc4\lib -o bin\Debug\5x5console.exe obj\Debug\main.o -lws2_32 -lDaemonBase

ne FONCTIONNE PAS

mais

gcc.exe -L..\DaemonBase\bin\Debug\ -LC:\MinGW\gcc4\lib -o bin\Debug\5x5console.exe obj\Debug\main.o -lDaemonBase -lws2_32

fonctionne nickel

neutral

Pourquoi il faut lier avec la lib statique d'abord? neutral

une demi journée pour ça? sick

5

C'est bizarre en effet... mais c'est un peu bizarre aussi de créer une lib statique qui appelle des fonctions qu'elle n'importe pas et qui ne sont pas directement membres du projet dans lequel elle va être utilisée, pourquoi fais-tu ça ?

(et au passage je vois pas pourquoi tu parles de relogement, ça n'a pas de rapport ^^)
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

6

bon oui il failait à l'étape de la recherche des symboles mais c'est un abus de langage trioui

pourquoi? parce que winsock est une DLL, et que j'y peux rien si mon code libifié y fait appel. socket() et consorts ne sont pas des fonctions si tordues.

une lib statique, c'est juste un "zip d'objets", ça n'est pas lié à quoi que ce soit ^^

edit: c'est un peu le cas tout le temps en fait, par exemple sous nunux, dès que tu fais une lib statique qui contient un appel à printf, cette fonction se trouve en fait dans la libc, qui est une "dll" non directement lié à ta lib statique grin

7

J'ai déjà vu ça, c'est la même chose en C et en C++...

Ils disent ça dans la doc de gcc :

It makes a difference where in the command you write this option;
the linker searches and processes libraries and object files in
the order they are specified. Thus, `foo.o -lz bar.o' searches
library `z' after file `foo.o' but before `bar.o'. If `bar.o'
refers to functions in `z', those functions may not be loaded.

Donc ce qu'il faut faire, c'est mettre les librairies qui utilisent les autres en premier.
En fait, ça permet d'accélérer la compilation et de simplifier l'écriture des compilateurs :
on ne conserve que la liste que des objets/fonctions non encore résolus.
Cela dit, c'est très chiant à utiliser.

D'ailleurs j'avais une question : Visual C/C++ et MingW ne sont pas du tout compatible pour les dll/les libs statiques?

8

pour le C, oui, pour le C++, absolument pas grin Le name mangling est différent, et les mécanismes d'exceptions sont incompatibles (au moins pour gcc4)

flemme d'appuyer mes dires, mais on trouve cette info sur google smile

9

L'ordre de linking est effectivement essentiel avec GNU ld, sauf si on utilise les groupes: -Wl,-( -lws2_32 -lDaemonBase -Wl,-) devrait fonctionner.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

10

donc en gros faut mettre par ordre de dépendance, et les dernières libs complètent les premières smile

11

Oui, pour des raisons de vitesse. Si tu utilises un groupe, ld cherche les symboles dans toutes les libs, et c'est plus lent que de traîter les libs dans l'ordre, c'est pour ça que cette dernière est la méthode par défaut (contrairement à certains autres linkers, comme par exemple ld-tigcc où nous n'avons pas considéré particulièrement la vitesse).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

12

13

Ça a certains avantages pour certains frameworks (je pense à lex/yacc qui donne un main si tu n'en fournis pas, alors que sous Visual tu aurais une erreur Duplicate Symbol), mais je ne connais pas d'autre avantage (j'ignorais l'argument de la vitesse).

Au passage, ce que fait le linker de MinGW quand on lui passe directement une DLL Win32 est déconseillé, ce qu'il faudrait c'est un vrai convertisseur de .lib d'importation en .a (plutôt qu'un outil qui génère le .a à partir de la DLL).

Malheureusement, j'ignore si le format d'un .lib d'importation est documenté.
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

14

dlltool, ou dllwrap ne font pas ça? (pas eu besoin de m'en servir jusqu'a présent)

C:\Documents and Settings\moi>c:\MinGW\gcc4\bin\dllwrap.exe --help
Usage c:\MinGW\gcc4\bin\dllwrap.exe <option(s)> <object-file(s)>
  Generic options:
   @<file>                Read options from <file>
   --quiet, -q            Work quietly
   --verbose, -v          Verbose
   --version              Print dllwrap version
   --implib <outname>     Synonym for --output-lib
  Options for c:\MinGW\gcc4\bin\dllwrap.exe:
   --driver-name <driver> Defaults to "gcc"
   --driver-flags <flags> Override default ld flags
   --dlltool-name <dlltool> Defaults to "dlltool"
   --entry <entry>        Specify alternate DLL entry point
   --image-base <base>    Specify image base address
   --target <machine>     i386-cygwin32 or i386-mingw32
   --dry-run              Show what needs to be run
   --mno-cygwin           Create Mingw DLL
  Options passed to DLLTOOL:
   --machine <machine>
   --output-exp <outname> Generate export file.
   --output-lib <outname> Generate input library.
   --add-indirect         Add dll indirects to export file.
   --dllname <name>       Name of input dll to put into output lib.
   --def <deffile>        Name input .def file
   --output-def <deffile> Name output .def file
   --export-all-symbols     Export all symbols to .def
   --no-export-all-symbols  Only export .drectve symbols
   --exclude-symbols <list> Exclude <list> from .def
   --no-default-excludes    Zap default exclude symbols
   --base-file <basefile> Read linker generated base file
   --no-idata4           Don't generate idata$4 section
   --no-idata5           Don't generate idata$5 section
   -U                     Add underscores to .lib
   -k                     Kill @<n> from exported names
   --add-stdcall-alias    Add aliases without @<n>
   --as <name>            Use <name> for assembler
   --nodelete             Keep temp files.
   --no-leading-underscore  Entrypoint without underscore
   --leading-underscore     Entrypoint with underscore.
  Rest are passed unmodified to the language driver


Report bugs to <http://www.sourceware.org/bugzilla/>

C:\Documents and Settings\moi>c:\MinGW\gcc4\bin\dlltool --help
Usage c:\MinGW\gcc4\bin\dlltool <option(s)> <object-file(s)>
   -m --machine <machine>    Create as DLL for <machine>.  [default: i386]
        possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, ppc, thumb
   -e --output-exp <outname> Generate an export file.
   -l --output-lib <outname> Generate an interface library.
   -y --output-delaylib <outname> Create a delay-import library.
   -a --add-indirect         Add dll indirects to export file.
   -D --dllname <name>       Name of input dll to put into interface lib.
   -d --input-def <deffile>  Name of .def file to be read in.
   -z --output-def <deffile> Name of .def file to be created.
      --export-all-symbols   Export all symbols to .def
      --no-export-all-symbols  Only export listed symbols
      --exclude-symbols <list> Don't export <list>
      --no-default-excludes  Clear default exclude symbols
   -b --base-file <basefile> Read linker generated base file.
   -x --no-idata4            Don't generate idata$4 section.
   -c --no-idata5            Don't generate idata$5 section.
      --use-nul-prefixed-import-tables Use zero prefixed idata$4 and idata$5.
   -U --add-underscore       Add underscores to all symbols in interface library.
      --add-stdcall-underscore Add underscores to stdcall symbols in interface library.
      --no-leading-underscore All symbols shouldn't be prefixed by an underscore.
      --leading-underscore   All symbols should be prefixed by an underscore.
   -k --kill-at              Kill @<n> from exported names.
   -A --add-stdcall-alias    Add aliases without @<n>.
   -p --ext-prefix-alias <prefix> Add aliases with <prefix>.
   -S --as <name>            Use <name> for assembler.
   -f --as-flags <flags>     Pass <flags> to the assembler.
   -C --compat-implib        Create backward compatible import library.
   -n --no-delete            Keep temp files (repeat for extra preservation).
   -t --temp-prefix <prefix> Use <prefix> to construct temp file names.
   -I --identify <implib>    Report the name of the DLL associated with <implib>.
      --identify-strict      Causes --identify to report error when multiple DLLs.
   -v --verbose              Be verbose.
   -V --version              Display the program version.
   -h --help                 Display this information.
   @<file>                   Read options from <file>.
Report bugs to <http://www.sourceware.org/bugzilla/>

OK pour yacc, je pensais que cette histoire était résolue avec des symboles weak qu'on pouvait redéfinir avec des symboles normaux.

15

Il y a aussi l'option -Wl,--start-group <liste de libs> -Wl,--end-group qui permet de faire une sorte de liste cyclique jusqu'à ce que les symboles soient résolus.
Gare à celui qui touche a mes chips quand je code !

16

non mais... je voulais juste regrouper 3 fichiers sources, une lib, et faire une référence à une DLL, c'est pas sorcier quand même grin

J'ai besoin de passer explicitement des options au linker pour ça? trifus

je refuse l'usine a gaz dont tu parles, et qui au demeurant a été déja présentée par Kevin.

17

Pour yacc, peut-être: Je ne savais pas qu'on pouvait faire des symboles "weak".
Pour dlltool/dllwrap, je ne sais pas. Il faudrait que je regarde en détail ce qu'ils acceptent comme fichiers d'entrée (.dll, .lib, .o, .a).
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

18

squalyl (./16) :
je refuse l'usine a gaz dont tu parles, et qui au demeurant a été déja présentée par Kevin.


ouais bon désolé, j'avais pas vu.

Usine à gaz ? quelle usine à gaz ? Certains linker comme ceux d'IBM implémentent cette fonctionnalité par défaut sous AIX.

Tu auras beau refuser, si ça ne compile pas tu pourras toujours mettre ton code derrière l'oreille...
Gare à celui qui touche a mes chips quand je code !

19

je répète la simplicité du code que je compile, sous WIN, le truc le plus basique possible , le truc de gol quoi, simple.

je m'en tape que ce soit par défaut sous aix, tout ce que je demande c'est que ce soit implicite et que j'aie pas besoin de lignes de commande à rallonge avec des -Wl,machin start group et compagnie -- pour faire ce truc que tout le monde doit faire 10 fois par semaine avec msvc, sans même se poser la question.

20

Ben utilise MSVC, que veux-tu qu'on te dise grin

(et de toute façon, si t'aimes pas les usines à gaz, GCC n'est pas un bon choix cheeky)
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

21

squalyl (./19) :
je répète la simplicité du code que je compile, sous WIN, le truc le plus basique possible , le truc de gol.gif quoi, simple.


Au vue de ./1, je dirai pas que c'est le truc le plus simple possible chew


smile

22

c'est vrai, mais le code sera porté sous linux, alors j'ai voulu me préparer embarrassed