Linkowanie statyczne takie samo jak w Go

1

Wczoraj testowałem aplikację rclone na Windows, aplikacja konsolowa 48MB technologia GO
z tego co sprawdzałem to EXE nie importuje żadnych DLL oprócz kernel32.dll
zastanawiam się czy platforma GO jest samowystarczalna i nie ma zewnętrznych zależności czy też biblioteki są umieszczone w zasobach EXE i tym sposobem ładowane

da się coś takiego zrobić w C++ ? Jeden exe i wszystkie zależności w jednym pliku

3
$ g++ -Wall hello.cpp 
$ ldd ./a.out 
	linux-vdso.so.1 (0x00007ffe4335f000)
	libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fce5e600000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fce5e200000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fce5e519000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fce5e89a000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fce5e84f000)
$ g++ -Wall -static hello.cpp 
$ ldd ./a.out 
	not a dynamic executable
5

da się coś takiego zrobić w C++ ?

Da się, to się nazywa linkowanie statyczne.

Edit: da się na unixach, nie wiem czy na 100% na Windowsie też - ale pobieżny rzut okiem w Google o msvc static linking sugeruje, że powinno coś takiego istnieć.

4

buduje się biblioteki jako biblioteki statyczne, linkuje potem te biblioteki i gotowe.
W cmake po prostu:

add_library(someLib STATIC)
...
add_executable(app)
...
target_link_libraries(app PRIVATE someLib)

Jak przy add_library nie ma STATIC to wtedy można to kontrolować za pomocą BUILD_SHARED_LIBS=OFF

Z powodu fragmentacji Linux statyczne linkowanie się praktykuje, by ograniczyć ból głowy dostarczania osobnej instalki na daną dystrybucję.

2

Oprocz tego co wspomnieli przedmowcy, zadna biblioteka nawet zlinkowana statycznie nie dziala w prozni. Tzn niewazne ile warstw posrednich zostanie narzuconych, wszystko i tak sprowadza sie do systemowych calli (Windows API w przypadku Windowsa).
Dlaczego nie ma tych calli skoro linkujemy statycznie i dlaczego jest tylko kernel32?
Ano dlatego, ze w kernel32 (tak naprawde jest to juz inna .dll ale mniejsza o to) jest funkcja LoadLibrary oraz GetProcAddress. Pointery na funkcje sa pobierane w runtime. Niektore appki stosuja takie podejscie, zeby podniesc kompatybilnosc pomiedzy wydaniami Windowsa, bez tego obraz wykonywalny nie zaladowalby sie do pamieci i user dostalby na twarz brzydki komunikat odnosnie brakujacej funkcji w jakiejs systemowej dll.

1

Tak, to bardziej problem polityczny i związany z tradycją niż technologiczny. C/C++ używa dynamicznych libek, bo tak się kiedyś robiło (mniejsza liczba bibliotek, mało ramu/dysku, brak optymalizacji takich jak LTO/usuwanie nieużywanych symboli) + cały ruch GNU mocno to rozpropagował. W dzisiejszych czasach ma to trochę mniejszy sens, w przypadku aplikacji serwerowych (go był projektowany pod to) nie ma to absolutnie żadnego sensu.

Nie wiem jak jest w przypadku windowsa ale w przypadku linuxa nie da się tego zrobić z libc (używanego praktycznie wszędzie), bo licencja GPL zabrania. Alternatywą jest użycie biblioteki musl znanej z alpine linux: budowanie z tą libką to standardowa praktyka tworzenia przenośnych binarek dla programów napisanych w Ruscie

0

Sprawdziłem na Windows Msys2 clang 15.0.7 i działa przynajmniej na małym projekcie, na większej kobyle w wolnym czasie.

Do pytania natchnęło mnie też trafienie na to repozytorium https://github.com/AnClark/msys2-qt6base-static
Ciekawe ile by miała statycznie linkowana aplikacja w "Qt Hello world z jednym QWidget" , pewnie minimum 66MB bo tyle mają wszystkie DLL+EXE razem
I trzeba jeszcze za tą przyjemność statycznego linkowania zapłacić :( Bo chyba licencja jest tylko na LGPL

4
slsy napisał(a):

Tak, to bardziej problem polityczny i związany z tradycją niż technologiczny. C/C++ używa dynamicznych libek, bo tak się kiedyś robiło (mniejsza liczba bibliotek, mało ramu/dysku, brak optymalizacji takich jak LTO/usuwanie nieużywanych symboli) + cały ruch GNU mocno to rozpropagował. W dzisiejszych czasach ma to trochę mniejszy sens, w przypadku aplikacji serwerowych (go

  1. W standardzie C++ nie ma nic o bibliotekach dynamicznych
  2. To linkowanie statycznie kiedyś było standardem i nadal jest na małych systemach wbudowanych.
  3. Dynamiczne biblioteki mają kilka ważnych zalet, które czynią je bardzo użytecznymi:
  • łatwość podmieniania fragmentu kodu
  • możliwość tworzenia pluginów
  • szybszy proces budowania projektu
  • słabsza relacja między fragmentami kodu dająca wieksża elastycznosć i konfigurowalność
  • możliwość współdzielenia zasobów, między wieloma procesami
  • możliwość sprzedawania produktu w kawałkach
  • ...

Wady:

  • konieczność utrzymywania binary compatibility
  • narzut wydajności związany ze słabym dowiązaniem
  • konieczność opublikowania niektórych symboli
  • możliwość wstrzyknięcia obcego kodu
  • ....

Te twoje sugestie, że to jakieś przestarzałe podejście jest dla mnie niezrozumiałe.
Oprogramowanie optymalizuje się według potrzeb. Czasami lepiej mieć dużo bibliotek dll, czasami lepiej ani jednej, a innym razem trzeba likować jedne fragmenty kodu statycznie.
Każdemu według potrzeb lub wydumanej specyfikacji użytkownika.
To że w twoim projekcie likuje się wszystko statycznie, nie oznacza od razu, że coś jest przestarzałe i niepotrzebne.

1
MarekR22 napisał(a):
  1. W standardzie C++ nie ma nic o bibliotekach dynamicznych

Tak jak nic nie ma o tym, że standardowa biblioteka musi trzymać ABI. Standard mało mnie interesuje, ważne jest zachowanie implementacji

Dynamiczne biblioteki mają kilka ważnych zalet, które czynią je bardzo użytecznymi:

Nie mówię, że nie. Static vs dynamic to bardzo subiektywna dyskusja i według mnie dynamiczne linkowanie jest zbyt często używane przez co cały ekosystem jest tak bardzo skrojony przez ten model, że wybór jest ciężki. Zauważ też, że oba nowe i popularne języki (Go i Rust) są linkowanie czysto statycznie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1