C:使用Makefile创建静态库和链接

C:使用Makefile创建静态库和链接,c,makefile,static-libraries,C,Makefile,Static Libraries,我正在努力 我想执行以下操作来创建一个单独编译和链接的makefile,从而创建和链接一个静态库 在形成最终静态可执行文件时 我有下面的Makefile代码,但是我得到了下面的错误 Makefile:13:**缺少分隔符。停止。 但我也试图理解如何实际链接/创建库 如果我在终端中的第12行之后运行命令,它们会工作,但不会在makefile中运行 myProgram: main.o addSorted.o freeLinks.o gcc -lm -o myProgram main.o ad

我正在努力

我想执行以下操作来创建一个单独编译和链接的makefile,从而创建和链接一个静态库 在形成最终静态可执行文件时

我有下面的Makefile代码,但是我得到了下面的错误

Makefile:13:**缺少分隔符。停止。

但我也试图理解如何实际链接/创建库

如果我在终端中的
第12行之后运行命令,它们会工作,但不会在makefile中运行

myProgram: main.o addSorted.o freeLinks.o
    gcc -lm -o myProgram main.o addSorted.o freeLinks.o

main.o: main.c
    gcc -O -c -lm main.c main.h

addSorted.o: addSorted.c addSorted.h
    gcc -O -c -lm addSorted.c

freeLinks.o: freeLinks.c freeLinks.h
    gcc -O -c -lm freeLinks.c

ar rc libmylib.a main.o addSorted.o freeLinks.o    //Error Line

ranlib libmylib.a

gcc -o foo -L. -lmylib foo.o

clean:
    rm -f myProgram main.o addSorted.o freeLinks.o
另外,如果您能帮助改进代码,我将不胜感激。

尝试以下方法:

all: myProgram

myProgram: main.o libmylib.a #libmylib.a is the dependency for the executable
        gcc -lm -o myProgram main.o -L. -lmylib

main.o: main.c
        gcc -O -c main.c main.h

addSorted.o: addSorted.c addSorted.h
        gcc -O -c addSorted.c

freeLinks.o: freeLinks.c freeLinks.h
        gcc -O -c freeLinks.c

libmylib.a: addSorted.o freeLinks.o #let's link library files into a static library
        ar rcs libmylib.a addSorted.o freeLinks.o

libs: libmylib.a

clean:
        rm -f myProgram *.o *.a *.gch #This way is cleaner than your clean
这组规则首先编译所有文件,然后使库(libmylib.a)成为目标,并使用其工件链接可执行文件。 我还添加了单独的冗余目标表单,只生成libs。 所需文件:

user@host> ls
addSorted.c  addSorted.h  freeLinks.c  freeLinks.h  main.c  main.h Makefile

生成文件不是shell脚本。这是一个配置文件 用于专家系统。特别是一个专家系统 知道如何高效地创建文件及其 具有最少重新生成不需要的文件的依赖项 重新制作

如果你看一下你的第一条规则:

myProgram: main.o addSorted.o freeLinks.o
    gcc -lm -o myProgram main.o addSorted.o freeLinks.o
这将告诉系统如何生成名为“myProgram”的文件,如果 决定它需要这样做。结肠后的部分 是myProgram需要的文件。如果他们不在那里,或者 make认为它们过时了,make会设法找到一些 可用于创建或更新它们的配方。一旦 所有这些都完成了,make然后执行“gcc…”行并 假定将创建或更新myProgram

您拥有的ar和ranlib行与所需的语法不匹配 生成文件规则。从他们的外表看,他们似乎是 制作libmylib.a.的配方。如果你把它们放进 syntax make需要说明的是,您得到:

libmylib.a: main.o addSorted.o freeLinks.o
    ar rcu libmylib.a main.o addSorted.o freeLinks.o
    ranlib libmylib.a
myProgram应该依赖于库本身,而不是 库的内容,最好将库选项放在 最后:

如果愿意,可以使用一个选项告诉gcc查找库 在当前目录中:

gcc -L. -o myProgram main.o -lmylib -lm
还有一些makefile变量可以帮助您不必重复 如此之多,所以我将第一条规则写为:

myProgram: libmylib.a
    gcc -L. -o $@ -lmylib -lm
然而,main.o实际上不太可能是库的一部分, 因此:

这里的$+表示“所有依赖项文件名”

最后,如果您希望gcc生成一个实际的静态可执行文件,而不是 只需使用您创建的库,您需要传递'-static'选项
到gcc。

三个
ar
ranlib
gcc
行的可能重复应该是什么目标的配方?@EtanReisner我对C/makefile和库不熟悉。我猜我的程序是
myProgram
。这就是我需要帮助的原因。另外,我得到错误的那一行,不包含
tab
Q:“我得到错误的那一行,不包含tab…”答:这就是问题所在。您需要一个“target”(例如,
mylib.a
,左对齐),后跟以“tab”开头的两行(
ar rc libmylib.a main.o addSorted.o freeLinks.o
,然后是
ranlib libmylib.a
)。这两行必须是连续的(没有中间的空白行)。这里有一个很好的教程:gcc链接器按照命令行参数的列出顺序处理这些参数。链接器不会包含库中的任何内容,除非存在满足需要的未解析名称。因此,不会从数学库链接任何内容。建议将'-lm'移动到链接器命令行的末尾。因此,库仅由所有文件生成,除了
main
?。一旦我创建了库,它就会链接到
myProgram
?这很有帮助。
共享库
也会同样工作吗?或者我必须从
main
@user3337714调用相同的函数,也就是说。您还可以为每个非主文件构建单独的库,或者将一组文件链接到一个库中,将另一组文件链接到另一个库中。只需按照您想要的方式创建库,按文件的用途连接文件,以保持项目结构的清晰性即可。@Dmitri当然忘了删除它。更正了答案。@user3337714共享库应从Makefile的角度同时生成。只需使用
-fpic
-shared
链接编译
*.o
文件。这里有一个很好的解释(不仅仅是关于makefiles,共享libs):您还可以为我解释一下共享库吗?共享库高度依赖于您所使用的系统。在x86或x86_64 linux上,除其他外,您需要使用-fpic编译对象文件。其他系统可能会有所不同。
myProgram: libmylib.a
    gcc -L. -o $@ -lmylib -lm
myProgram: main.o libmylib.a
    gcc -L. -o $@ $< -lmylib -lm
libmylib.a: addSorted.o freeLinks.o
    ar rcu $@ $+
    ranlib $@