由编译错误看L. lxxxx的正确位置

问题:

在研究一个问题时,碰到了新的问题。知道了-L. -lmyhello的正确放置位置。

要研究的问题是:除了-static参数之外,使用静态库和使用动态库编译成目标程序使用的gcc命令完全一样,那当动态库和静态库同名时,gcc命令会优先使用哪个库?

研究的范围在lib_test目录下有如下的文件:

dingq@wd-u1110:~/wrk/tmp/lib_test$ ll
total 16
-rw-rw-r-- 1 dingq dingq 518 2012-07-31 10:17 hello.c
-rw-rw-r-- 1 dingq dingq 519 2012-07-31 10:22 hello.h
-rw-rw-r-- 1 dingq dingq 501 2012-07-31 13:51 main.c
-rw-rw-r-- 1 dingq dingq 542 2012-07-31 14:07 Makefile

解决办法:

1. 单条执行命令:

gcc -g3 -Wall -o0 -c hello.c -o hello.o

只编译不链接。

ar cr libmyhello.a hello.o

生成静态库。

gcc -fPIC -shared -o libmyhello.so hello.o
生成动态库。

gcc -o hello main.c -L. -lmyhello
生成目标程序hello。

都能成功运行,得到所需要的文件。

后来,为了编译方便,添加了Makefile文件,其中,将生成目标程序hello的执行过程写为:

hello : $(OBJS)
	$(CC) $(LDFLAGS) -o hello main.c
前面的变量设定为:

CROSS_COMPILE =
PREFIX = $(CROSS_COMPILE)
CC = $(PREFIX)gcc

CCFLAGS = -g3 -Wall -o0
LD = $(CC)
LDFLAGS = -L. -lmyhello
AR = $(PREFIX)ar
ARFLAGS = cr

RM = -rm -f

SRCS = hello.c
OBJS = $(SRCS:%.c=%.o)

.PHONY : all
all: lib_a lib_so hello

%.o : %.c
	$(CC) $(CCFLAGS) -c $< -o $@

在make的时候总是出错,错误信息如下:

/tmp/ccgznsuX.o: In function `main':
main.c:(.text+0x11): undefined reference to `hello'
collect2: ld returned 1 exit status
但是,单条命令执行的时候又是对的。
2. 经反复对比发现,原来单条命令执行的时候,命令为:

gcc -o hello main.c -L. -lmyhello
而在Makefile中,命令则改为:

gcc -L. -lmyhello -o hello main.c
为了验证确实是-L. -lmyhello的位置导致了编译出现错误,单独在命令行中执行命令:

gcc -L. -lmyhello -o hello main.c

确实出现了错误信息。

这说明,确实是-L. -lmyhello的位置导致了编译错误的出现。


所以,库文件最好放在编译链接命令的最后端,不是放在目标程序的前面,而是在目标程序的后面。



原文地址:https://www.cnblogs.com/java20130726/p/3218545.html