[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)
 * [email protected]
 * 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)
 * [email protected]
 * 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)
#  [email protected]
#  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.

猜你喜欢

转载自www.cnblogs.com/dramalife-wjy/p/note__70-gcc_gnu_compiler_collection__ld__sample_ld_as-needed.html
今日推荐