[Linux][C][gcc] Linux GCC 編譯鏈接 報錯ex: ./libxxx.so: undefined reference to `shm_open'


本人原創文章,文章是在此代碼github/note的基礎上進行補充,轉載請注明出處:https://github.com/dramalife/note。

以librt丶用戶自定義動態庫libxxx 和 用戶應用程序app為例,討論編譯鏈接過程中出現的錯誤,
其中app依賴libxxx,libxxx依賴librt。

關鍵詞:“ undefined reference to”。

1 源文件

1.1 app.c

/*
 * [note](github.com/dramalife/note.git)
 * Dramalife@live.com
 * Init : 2020.03.04
 */
#include <stdio.h>

extern void func_in_libxxx(void);

int main(void)
{
	printf("File:%12s,Func:%14s,Line:%4d. \n",__FILE__,__func__,__LINE__);
	func_in_libxxx();
	return 0;
}

1.2 libxxx.c

/*
 * [note](github.com/dramalife/note.git)
 * Dramalife@live.com
 * Init : 2020.03.04
 */

/* shm related */
#include <sys/mman.h>
#include <sys/stat.h>        /* For mode constants */
#include <fcntl.h>           /* For O_* constants */

#include <stdio.h>

void func_in_libxxx(void)
{
	printf("File:%12s,Func:%14s,Line:%4d. \n",__FILE__,__func__,__LINE__);
	shm_open("abcd",O_RDWR, 0);
}

1.3 Makefile

# 
#  [note](github.com/dramalife/note.git)
#  Dramalife@live.com
#  Init : 2020.03.04
# 

all : dynlib app_out

app_out:
	gcc -o app.out app.c -Wl,-rpath=. -L. -lxxx -lrt

dynlib:
	gcc -o libxxx.so libxxx.c -fPIC -shared

clean:
	rm -rvf ./*.out ./*.so


######### Targets for testing !!! #########
# Target - no "-lrt"
app_err_lrt:
	gcc -o app.out app.c -Wl,-rpath=. -L. -lxxx
# Target - add "-Wl,--as-needed"
app_err_asneeded:
	gcc -o app.out app.c -L. -Wl,-rpath=. -Wl,--as-needed -lrt -lxxx

2 編譯

2.1 編譯動態庫

# make dynlib 
gcc -o libxxx.so libxxx.c -fPIC -shared

2.2 編譯程序文件錯誤1 - 缺少鏈接庫

缺少鏈接動態庫的情況-lrt

# make app_err_lrt 
gcc -o app.out app.c -Wl,-rpath=. -L. -lxxx
./libxxx.so: undefined reference to `shm_open'
collect2: error: ld returned 1 exit status
makefile:22: recipe for target 'app_err_lrt' failed
make: *** [app_err_lrt] Error 1

2.3 編譯程序文件錯誤2 - 錯誤使用鏈接選項

由於鏈接選項導致的編譯錯誤

# make app_err_asneeded 
gcc -o app.out app.c -L. -Wl,-rpath=. -Wl,--as-needed -lrt -lxxx
./libxxx.so: undefined reference to `shm_open'
collect2: error: ld returned 1 exit status
makefile:25: recipe for target 'app_err_asneeded' failed
make: *** [app_err_asneeded] Error 1

3 結論

錯誤1出現的原因是鏈接時缺少對必要庫的指定。
錯誤2出現的原因是“-Wl,--as-needed”向ld傳遞的參數,手冊中對這個選項的說明如下(LD(1)):

 --as-needed
 --no-as-needed
           This option affects ELF DT_NEEDED tags for dynamic libraries mentioned on the command line after the --as-needed option.  Normally the linker will add a
           DT_NEEDED tag for each dynamic library mentioned on the command line, regardless of whether the library is actually needed or not.  --as-needed causes a
           DT_NEEDED tag to only be emitted for a library that at that point in the link satisfies a non-weak undefined symbol reference from a regular object file or, if
           the library is not found in the DT_NEEDED lists of other needed libraries, a non-weak undefined symbol reference from another needed dynamic library.  Object
           files or libraries appearing on the command line after the library in question do not affect whether the library is seen as needed.  This is similar to the
           rules for extraction of object files from archives.  --no-as-needed restores the default behaviour.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM