Próbuję skompilować ten kod źródłowy z pliku makefile w VPS, ale nie działa. VPS to 64-centowy system operacyjny
Oto pełny błąd
# make
gcc -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/amx/*.c
g++ -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/*.cpp
g++ -c -O3 -w -DLINUX -I../SDK/amx/ *.cpp
g++ -O2 -fshort-wchar -shared -o "TCP_V1.so" *.o
/usr/bin/ld: TCP-LINUX_V1.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
TCP-LINUX_V1.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [all] Error 1
Oto mój plik makefile:
GPP=g++
GCC=gcc
OUTFILE="TCP_V1.so"
COMPILE_FLAGS=-c -O3 -w -DLINUX -I../SDK/amx/
all:
$(GCC) $(COMPILE_FLAGS) ../SDK/amx/*.c
$(GPP) $(COMPILE_FLAGS) ../SDK/*.cpp
$(GPP) $(COMPILE_FLAGS) *.cpp
$(GPP) -O2 -fshort-wchar -shared -o $(OUTFILE) *.o
Czy ktoś wie, co się stało?
recompile with -fPIC
?COMPILE_FLAGS=-c -O3 -w -DLINUX -fPIC -I../SDK/amx/
Odpowiedzi:
Rób to, co każe Ci kompilator, czyli przekompiluj z
-fPIC
. Aby dowiedzieć się, do czego służy ta flaga i dlaczego jest ona potrzebna w tym przypadku, zobacz Opcje generowania kodu w podręczniku GCC.W skrócie, termin kod niezależny od pozycji (PIC) odnosi się do wygenerowanego kodu maszynowego, który jest niezależny od adresu pamięci, tj. Nie przyjmuje żadnych założeń co do miejsca załadowania go do pamięci RAM. Jedynie kod niezależny od pozycji powinien być zawarty w obiektach współdzielonych (SO), ponieważ powinny one mieć możliwość dynamicznej zmiany położenia w pamięci RAM.
Wreszcie możesz o tym poczytać również na Wikipedii .
źródło
-fPIC
do wszystkich wywołań kompilatora dla wszystkich plików źródłowych (jednostek tłumaczeniowych, np.*.cpp
Plików) biblioteki. Konkretny sposób wykonania tego zależy od używanego systemu kompilacji. Na przykład w CMake możesz wydaćset_target_properties(${LIBRARY_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
. W przypadku tego gościa (używającego zwykłego starego Make) musiałby to zrobić,COMPILE_FLAGS+=-fPIC
ponieważ używa tej zmiennej do oznaczenia zestawu flag kompilacji dla wszystkich plików źródłowych swojej biblioteki.W moim przypadku ten błąd wystąpił, ponieważ
make
polecenie oczekiwało pobrania udostępnionych bibliotek (*.so
plików) ze zdalnego katalogu wskazanego przezLDFLAGS
zmienną środowiskową. Przez pomyłkę były tam dostępne tylko biblioteki statyczne (*.la
lub*.a
pliki).Dlatego mój problem nie dotyczył programu, który kompilowałem, ale zdalnych bibliotek, które próbowałem pobrać. Nie musiałem więc dodawać żadnej flagi (powiedzmy
-fPIC
) do kompilacji przerwanej przez błąd relokacji. Zamiast tego ponownie skompilowałem zdalną bibliotekę, aby udostępnione obiekty były dostępne.Zasadniczo był to błąd polegający na nie znalezieniu pliku w przebraniu.
W moim przypadku musiałem usunąć niewłaściwie umieszczony
--disable-shared
przełącznik wconfigure
wywołaniu wymaganego programu, ponieważ domyślnie zostały zbudowane biblioteki współdzielone i statyczne.Zauważyłem, że większość programów buduje oba typy bibliotek w tym samym czasie, więc mój jest prawdopodobnie przypadkiem narożnym. Ogólnie rzecz biorąc, może się zdarzyć, że wolisz włączyć biblioteki współdzielone, w zależności od ustawień domyślnych.
Aby sprawdzić konkretną sytuację z przełącznikami kompilacji i ustawieniami domyślnymi, przeczytałbym podsumowanie, które pojawia się
./configure --help | less
, zwykle w sekcji Funkcje opcjonalne. Często stwierdzałem, że ten odczyt jest bardziej wiarygodny niż instrukcje instalacji, które nie są aktualizowane w miarę rozwoju programów zależności.źródło
Nie zawsze chodzi o flagi kompilacji, mam ten sam błąd na gentoo, kiedy używam distcc.
Powodem jest to, że na serwerze distcc używa profilu nieutwardzonego, a na kliencie profil jest wzmocniony. Sprawdź tę dyskusję: https://forums.gentoo.org/viewtopic-p-7463994.html
źródło
Naprawiono to z
-no-pie
opcją na etapie linkera:g++-8 -L"/home/pedro/workspace/project/lib" -no-pie ...
źródło
Po prostu wyczyszczenie projektu rozwiązało to dla mnie.
Mój projekt jest aplikacją C ++ (nie udostępnianą biblioteką). Przypadkowo otrzymałem ten błąd po wielu udanych kompilacjach.
źródło
Miałem ten sam problem. Spróbuj ponownie skompilować za pomocą
-fPIC
flagi.źródło
Otrzymuję to samo rozwiązanie, co komentarz @ camino na https://stackoverflow.com/a/19365454/10593190 i odpowiedź XavierStuvw .
Mam go do pracy (do instalacji ffmpeg), po prostu przeinstalowując całość od początku, a wszystkie wystąpienia
$ ./configure
zastąpione przez$ ./configure --enable-shared
(najpierw upewnij się, że usunąłeś wszystkie foldery i pliki, w tym pliki .so z poprzedniej próby).Najwyraźniej to działa, ponieważ https://stackoverflow.com/a/13812368/10593190 .
źródło