cannot specify -s with -c or -S with multiple files

来源:互联网 发布:fl studio12破解版mac 编辑:程序博客网 时间:2024/05/21 19:47

在修改一个Makefile时遇到了这个问题。
具体的情况为:

目录结构,其中liba1.c和liba1b.c都是含义一个函数的源文件,里面只有一个接口,显示内容为printf而已。

[zhang@zwfedora23 lib1]$ lsliba1b.c  liba1b.h  liba1.c  liba1.h  Makefile
LIBA1_SRC:=$(wildcard *.c)LIBA1_OBJ:=$(LIBA1_SRC:%.c=%.o)LIBA1_STATIC:=liba1.aCC=gccAR=ar.PHONY: all cleanall: $(LIBA1_OBJ) $(LIBA1_STATIC)$(LIBA1_OBJ):$(LIBA1_SRC)  $(CC) -c $^ -o $@$(LIBA1_STATIC):$(LIBA1_OBJ)  $(AR) -rcv $@ $^clean:  @rm -f $(LIBA1_STATIC)   @rm -f $(LIBA1_OBJ)

执行make的结果:

[zhang@zwfedora23 lib1]$ makegcc -c liba1.c liba1b.c -o liba1.ogcc: fatal error: cannot specify -o with -c, -S or -E with multiple filescompilation terminated.Makefile:15: recipe for target 'liba1.o' failedmake: *** [liba1.o] Error 1[zhang@zwfedora23 lib1]$

首先看到了那一句, cannot specify -o with -c ,-S or -E with multiple files.然后我就把目录中的liba1b.c和对应的liba1b.h修改了文件名后缀,为的是此目录只含有一个.c文件。

[zhang@zwfedora23 lib1]$ lsliba1.a  liba1b-c  liba1b-h  liba1.c  liba1.h  liba1.o  Makefile[zhang@zwfedora23 lib1]$

此时在执行make,即可以成功的生成.a文件,且这个.a文件中只包含一个.c文件。

[zhang@zwfedora23 lib1]$ makegcc -c liba1.c -o liba1.oar -rcv liba1.a liba1.oa - liba1.o[zhang@zwfedora23 lib1]$ lsliba1.a  liba1b-c  liba1b-h  liba1.c  liba1.h  liba1.o  Makefile[zhang@zwfedora23 lib1]$ 

难道gcc -c 这样的参数不适合多个源文件使用?
那如果这个.a文件需要多个.c文件生成怎么办?这个问题好像太蠢了,因为我之前已经编译了无数个库了,现在才来问这个问题,可见当时使用makefile也是稀里糊涂的使用,根本没有研究明白,现在好了,全都需要花时间补上。
去网上查了一下,当需要有多个源文件生成一个.a文件时采用的方法是把每个源文件生成的自己对应的.o文件,然后再把多个.o文件使用ar组合为一个整体的.a文件。

废话不说了,赶快想解决办法。
我现在需要做的就是把每个c源文件都生成一个o文件,然后把这些个object文件私用ar组织起来形成一个真正的a文件。
为了实现这样的目的,我又去搜了一下《跟我一起写Makefile》这篇文档,当时刚学makefile时也是看的它,但是没有完全看进去,现在需要从里面找一些能够实现上面的目标的操作,这个文档都看完看懂需要至少2个小时,没办法,从头开始来吧。不过好在刚看到静态模式,就感觉好像就可以解决我目前的问题了。我把我当前的目录结构贴出来看看,基本跟上面的一样,这是文件名换了。

[zhang@zwfedora23 libs]$ lslibs1.c  libs1.h  libs2.c  libs2.h  main.c  Makefile[zhang@zwfedora23 libs]$ 
SRC:=$(wildcard *.c)#OBJS:=$(wildcard *.o)OBJS := $(patsubst %.c,%.o,$(wildcard *.c))LIB_A := libs.aCC:=gccCFLAGS:= -I./.PNONY:all cleanall: $(LIB_A)clean:  @rm -f $(OBJS)  @rm -f $(LIB_A) #$(OBJS):$(SRC)# $(CC) -o $@ $^$(OBJS):%.o:%.c  $(CC) -c $(CFLAGS) $< -o $@$(LIB_A):$(OBJS)  $(AR) rcv $@ $^  @echo '$$@' = $@  @echo '$$^' = $^  @echo SRC=$(SRC)  @echo OBJS=$(OBJS)  #$(CC) -o $(LIB_A) $(OBJS)

执行结果:

[zhang@zwfedora23 libs]$ makegcc -c -I./ libs1.c -o libs1.ogcc -c -I./ libs2.c -o libs2.ogcc -c -I./ main.c -o main.oar rcv libs.a libs1.o libs2.o main.oa - libs1.oa - libs2.oa - main.o$@ = libs.a$^ = libs1.o libs2.o main.oSRC=libs1.c libs2.c main.cOBJS=libs1.o libs2.o main.o#gcc -o libs.a libs1.o libs2.o main.o[zhang@zwfedora23 libs]$ lslibs1.c  libs1.h  libs1.o  libs2.c  libs2.h  libs2.o  libs.a  main.c  main.o  Makefile[zhang@zwfedora23 libs]$ 

这时已经生成了盼望的.o文件和.a文件,为了验证一下这个.a文件是否正确,我又写了一个简单的main.c,然后编译:

[zhang@zwfedora23 libs]$ gcc main.c -ls -L./ -o test[zhang@zwfedora23 libs]$ ./test hellohello,libs2

可以看到test的输出是正确的,至此我的问题也解决了。

最后再总结一下之前没有成功的原因。
主要是没有给出生成.o文件的生成规则,只给出了

OBJS:=$(wildcard %.o)

这个表达式,当时以为OBJS就是包含*.o的变量了。实际上,OBJS的值确实是libs1.o libs2.o,但是问题是我没有给出怎么生成这两个object文件的规则,然后就认为执行完它就已经有object文件了,这样的想法简直太错误了。静下心来,认真的读了《跟我一起写Makefile》才认识到自己的愚蠢思维,漏洞太多。

0 0
原创粉丝点击