Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C] - libxml2, zlib, iconv - statyczne linkowanie (bez DLL), windows + gcc

07 Lut 2020 19:30 135 1
  • Poziom 17  
    Cześć,

    Od 3 dni męczę się (już w sumie pewnie z 10h~) z kompilacją a właściwie statycznym linkowaniem bibliotek .lib. Chciałbym zlinkować tą bibliotekę do operacji na danych w formacie XML http://xmlsoft.org/index.html ze swoim programem, korzystam z plików dostępnych tutaj: https://www.zlatkovic.com/projects/libxml/ a dokładniej tutaj: https://www.zlatkovic.com/pub/libxml/ - pobrałem następujące paczki:
    - iconv-1.9.2.win32.zip;
    - lib-1.2.5.win32.zip;
    - libxml2-2.7.8.win32.zip.
    W paczkach tych znajdują się foldery: bin, include, lib. Ja korzystam oczywiście z headerów z include (są potrzebne zarówno przy dynamicznych jak i statycznych bibliotekach) oraz z plików .lib z folderu lib, przekopiowałem je wszystkie do jednego folderu lib znajdującego się w tej samej lokalizacji co plik main.c.

    [C] - libxml2, zlib, iconv - statyczne linkowanie (bez DLL), windows + gcc

    Same pliki .lib:
    [C] - libxml2, zlib, iconv - statyczne linkowanie (bez DLL), windows + gcc

    Teraz używając CMD na windows 10 oraz MinGW z gcc wersją 8.2.0:
    Cytat:

    C:\Users\Szymon\Desktop\C_XML>gcc --version
    gcc (MinGW.org GCC-8.2.0-3) 8.2.0
    Copyright (C) 2018 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


    Moje pytanie brzmi: Jak to skompilować statycznie, żeby wyjściowy plik exe miał wszystko w sobie i nie potrzebował żadnych niestandardowych DLLek do działania?

    Program testowy main.c, który używam (gdy uda mi się stworzyć plik .exe z odwołaniem do .DLL to po wklejeniu DLLek dostępnych w folderach bin wymienionych bibliotek program ładnie wypisuje "works" w konsoli) - przy okazji zakomentowane komendy kompilatora, które już testowałem, i które nie zadziałały tak jakbym chciał:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    [/code]

    1. Używane komendy do kompilowanie jak wyżej i tak np, korzystając z:
    Cytat:
    gcc -Wall -Wextra -static main.c -o a.exe -Iinclude -Llib -llibxml2 -lzlib -liconv

    Otrzymuję plik a.exe, który wymaga pliku DLL:
    [C] - libxml2, zlib, iconv - statyczne linkowanie (bez DLL), windows + gcc
    Także screen z DependencyWalkera od MS (tutaj dziwne bo narzeka także na inne DLLki z np runtime library MSVCRT.DLL czy KERNERL32.DLL, ale zakładam, że póki co ze względu na error wyżej najważniejsze jest rozwiązanie kwestii z libxml2):
    [C] - libxml2, zlib, iconv - statyczne linkowanie (bez DLL), windows + gcc

    2. Identyczna sytuacja następuje przy użyciu komendy:
    Cytat:
    gcc -Wall -Wextra main.c -o a.exe -Iinclude -Llib -Wl,-Bstatic -llibxml2 -Wl,-Bstatic -lzlib -Wl,-Bstatic -liconv


    Dodałem do linkera przed każdym libem -Wl,-Bstatic żeby wymusić linkowanie statyczne (+ usunąłem -static z 1), szczerze to nie wiem czym się różnią te 2 komendy, patrząc na wynik niczym)

    3. Kolejna próba to najpierw stworzenie pliku a.o a potem zlinkowanie go z pozostałymi

    Cytat:

    gcc -Wall -Wextra -c main.c -o a.o -Iinclude
    gcc -Wall -Wextra -o a.exe a.o -Iinclude -Llib -llibxml2 -lzlib -liconv


    Wynik taki sam jak w 1) i 2)

    4. Tutaj zaczyna się dziać coś innego, jak pisałem wyżej są różne dostępne pliki .lib, czytając:
    Stack Overflow - 3 kinds of libraries on Windows
    Doszedłem do wniosku, że niektóre te pliki .dll mogą być właśnie nie object library a import library, tylko dla libxml2 są aż 3 pliki .lib:
    - libxml2.lib;
    - libxml2_a.lib;
    - libxml2a_a_dll.lib.
    I teraz mam całkowity mętlik w głowie co jest czym, podejrzewałbym, że libxml2a_a_dll.lib to jest właśnie import library bo ma w nazwie dll...

    W każdym razie użyłem tam gdzie mogłem plików z _a a dla zliba, gdzie takiego pliku .lib nie było zostawiłem użycie zlib.dll, przy kolejnych próbach przeniosłem liby do tego samego folderu gdzie main.c:
    [C] - libxml2, zlib, iconv - statyczne linkowanie (bez DLL), windows + gcc
    kolejna komenda:
    Cytat:

    gcc -static a.o iconv_a.lib zlib.lib libxml2_a.lib -o a.exe


    Tym razem zasypała mnie lista błędów (wrzucam w tag syntax=Ini żeby nie zawalić całej strony):
    Kod: Ini
    Zaloguj się, aby zobaczyć kod


    Teraz użyłem podobnej komendy jak wyżej, tylko .liby dałem w innej kolejności, gdzieś przeczytałem, że najbardziej zależny powinien być jako 1:
    5)
    Cytat:

    gcc -static a.o libxml2_a.lib iconv_a.lib zlib.lib -o a.exe


    Tym razem lista błędów jest o wiele krótsza:
    Kod: ini
    Zaloguj się, aby zobaczyć kod


    I to jest moja ostatnia próba, googlując:
    Cytat:

    warning: line number count (0x2) exceeds section size (0x1)


    Znalazłem kogoś, kto miał problemy z innym libem (1 link w google) i tam poradził, żeby użyć starszego gcc co też zrobiłem i co niestety nie pomogło... Stąd przychodzę na forum, ktoś z was tak jak ja próbował zlinkować statycznie libxml2 i mu się udało? Może robię jakiś podstawowy błąd, który osoba siedząca w temacie kompilatorów C zobaczy od razu. Dobrze by było także dowiedzieć się, dlaczego dla takiego libxml2 w folderze lib znalazły się aż 3 pliki .lib i jak rozpoznać, który należy użyć.

    Za poprawną odpowiedź z wytłumaczeniem co zrobiłem źle i jak należy to wykonać poprawnie 100 pkt (chciałbym ominąć używanie różnych menedżerów pakietów czy innych takich, które same mi dopasują flagi kompilacji ze względów edukacyjnych, chociaż takie rozwiązania też będą mile widziane).
  • Poziom 14  
    Zaznaczam że specalistą nie jestem.
    - błędy wydają się być efektem nieczytelnego dla gcc formatu plików lib (zwyczajnie nie zadziałają)
    - pliki .lib bez "a" to pradopodobnie "Import Library" (implib), służące wyłącznie automatyzacji dołączania dynamiczych bibliotek (jak się chce linkować statycznie to zbędne a nawet szkodliwe), dają się czasem rozpoznać po niewielkim rozmiarze
    - oczekiwane pliki bibliotek powinny być chyba z rozszerzeniem .a (tutaj jakby niektóre nazwy chciały mieć to .a ) https://stackoverflow.com/questions/6578484/telling-gcc-directly-to-link-a-library-statically
    Moje pomysły:
    - użyć msys2
    łatwo znaleźć gdzie pobrać
    po uruchomieniu msys2 w celu znalezienia pakietu można napisać
    pacman - Ss gcc
    a w celu instalacji
    pacman -S gcc (tutaj nazwa będzie nieco dłuższa)
    trzeba zainstalować potrzebne biblioteki
    powinno wtedy dać się budować jak wcześniej
    z gcc miałem problemy i używałem clang'a (składnia chyba identyczna) ale może tutaj takie nie wystąpią
    - budować dla uproszczenia jedną komendą (nie budować najpierw a.o)