我想在我的Makefile中将'ld'替换为'gcc'以链接我的内核对象

时间:2019-01-18 12:00:36

标签: gcc makefile ld gcov opensolaris

在我的项目中,我拥有用于​​构建Solaris内核模块的makefile,它们使用gcc编译文件,但是使用ld将所有.o文件链接在一起成为一个内核模块。我试图在构建中包括gcov(-fprofile-arcs)或tcov(-xprofile=tcov)之类的覆盖率选项,因此我也想在链接期间用ld替换gcc

但是,一旦我使用gcc替换ld,构建就开始失败,并出现许多“未定义符号”错误,即使我使用了一些编译标志并摆脱了这些错误,内核模块根本不会加载到我的Solaris内核中。

例如:

$ /usr/ccs/bin/ld -r -dy -Nstrmod/rpcmod -Nfs/nfs \
                  -Nmisc/rpcsec -Nmisc/klmmod -Nfs/zfs \
                  -o debug64/nfssrv \
                  debug64/nfs_server.o debug64/nfs_srv.o debug64/nfs3_srv.o \
                  debug64/nfs_acl_srv.o debug64/nfs_auth.o obj64/nfs41_srv.o \
                  obj64/ctl_ds_srv.o obj64/dserv_server.o

ld可以正常工作,但是使用gcc时出现以下错误:

/opt/gcc-4.4.4/bin/gcc -m64 -z muldefs \
                       -Lmod/rpcmod -Lfs/nfs -Lmisc/rpcsec \
                       -Lmisc/klmmod -Lfs/zfs \
                       -o obj64/nfssrv \
                       obj64/nfs_server.o obj64/nfs_srv.o obj64/nfs3_srv.o
                       obj64/nfs_acl_srv.o obj64/nfs_auth.o obj64/nfs41_srv.o 
                       obj64/ctl_ds_srv.o obj64/dserv_server.o

Undefined                       first referenced
 symbol                             in file
hz                                  obj64/nfs_server.o
p0                                  obj64/nfs_server.o
nfs_range_set                       obj64/nfs41_srv.o
getf                                obj64/nfs_server.o
log2                                obj64/nfs4_state.o
main                                /usr/lib/amd64/crt1.o
stoi                                obj64/ctl_ds_srv.o
dmu_object_alloc                    obj64/dserv_server.o
nvpair_name                         obj64/nfs4_srv.o
__dtrace_probe_nfss41__i__destroy_encap_session obj64/nfs41_srv.o
__dtrace_probe_nfssrv__i__dscp_freeing_device_entries obj64/ctl_ds_srv.o
mod_install                         obj64/nfs_server.o
xdr_faststatfs                      obj64/nfs_server.o
xdr_WRITE3res                       obj64/nfs_server.o
svc_pool_control                    obj64/nfs_server.o

2 个答案:

答案 0 :(得分:2)

警告选项-L允许指定搜索库的路径,指定要与您链接的库(也),必须使用选项-l

因此,您必须先添加选项-lrpcmod -lnfs -lrpcsec -lklmmod -lzfs

GCC Linking Options

中的更多详细信息

答案 1 :(得分:0)

默认情况下,通过gcc编译器驱动程序调用的GNU链接器将尝试创建标准可执行文件。因此,如果您没有其他说明,ld将使用其默认的链接程序脚本,C启动代码,并会寻找main()例程以及所有可生成有效可执行文件的程序。

我对Solaris不太熟悉,但是可以肯定,这不适用于构建内核模块。我希望内核模块至少需要一些选项,例如-ffreestanding-nostdlibs,并且很可能是一种非默认的链接脚本,该脚本可能与用于应用程序的默认链接脚本有很大差异。

即使您设法以这种方式链接内核模块,我也严重怀疑您是否会完成。 gcov检测例程最有可能不希望驻留在内核驱动程序中,而是希望有合适的C执行环境(例如,它至少希望fopen()个文件来fwrite()发现) 。但是,内核驱动程序没有这种舒适感。您可能会遇到问题,无法以某种方式从内核模块中获取gcov数据。

并不是说这是行不通的,但是肯定会做很多工作。