如何使用 C 源代码的 Makefile 创建静态库

Tom*_*Tom 2 c makefile

我想了解如何创建 Makefile。我有以下 Makefile:

DESTDIR=../../
PREFIX=../

STATIC=libdemo.a

CC = gcc
CFLAGS = -Wall -Winline -pipe

LDFLAGS = -L../../../lib
LIBS    = -lpthread 

SRC = demo1.c demo2.c

OBJ = $(SRC:.c=.o)

$(STATIC): $(OBJ)
        @echo "[Link (Static)]"
        @ar rcs $(STATIC) $(OBJ)

.c.o:
        @echo [Compile] $<
        @$(CC) -c $(CFLAGS) $< -o $@

clean:
        rm -f $(OBJ) *~ core tags *.bak Makefile.bak libgeniePi.*

.PHONEY:        install
install:        $(TARGET)
        @install -m 0755 libdemo.a  $(DESTDIR)$(PREFIX)/lib

all:
        gcc -g -Wall -o program program.c $(LDFLAGS) $(LIBS)
Run Code Online (Sandbox Code Playgroud)

这几乎符合我想要的。我从make文件 demo1.cdemo2.c. 我make install将库放在正确的目录中,并make all最终编译了使用该库的程序,一切都很好。

但是,该库libdemo.a是可执行的,我认为不应该是这样,对吧?

其次,如何使所有命令(makemake installmake all)按顺序运行而不是单独调用它们?

Eta*_*ner 5

您可以通过先决条件链接目标。

为了得到你想要的(并且make默认情况下这样做),你需要添加install作为你的目标的先决条件all(尽管我们将在一分钟内重命名它),并$(TARGET)install先决条件中替换为$(STATIC)或在作业中替换STATICTARGET目标线。

像这样的东西:

DESTDIR=../../
PREFIX=../

STATIC=libdemo.a

CC = gcc
CFLAGS = -Wall -Winline -pipe

LDFLAGS = -L../../../lib
LIBS    = -lpthread 

SRC = demo1.c demo2.c

OBJ = $(SRC:.c=.o)

$(STATIC): $(OBJ)
        @echo "[Link (Static)]"
        @ar rcs $@ $^

.c.o:
        @echo [Compile] $<
        @$(CC) -c $(CFLAGS) $< -o $@

clean:
        rm -f $(OBJ) *~ core tags *.bak Makefile.bak libgeniePi.*

.PHONY: install
install: $(STATIC)
        @install -m 0755 $< $(DESTDIR)$(PREFIX)/lib

all: install
        $(CC) -g -Wall -o program program.c $(LDFLAGS) $(LIBS)
Run Code Online (Sandbox Code Playgroud)

另请注意,我修复了您的.PHONEY拼写错误并使用$@,$^$<代替某些食谱中的显式文件/变量名称。

也就是说,这仍然会在您每次make all运行时进行重建。programprogram.c make all

要解决这个问题,您需要执行以下操作:

all: program

program: install program.c
    $(CC) -g -Wall -o $@ program.c $(LDFLAGS) $(LIBS)
Run Code Online (Sandbox Code Playgroud)

而不是你当前的all目标。

请注意,由于先决条件,我无法在该配方中使用$<$^来引用。另请注意,这实际上并不能解决“总是重建”问题(同样是由于先决条件)。program.cinstallinstall

解决重建问题的方法是根本不存在虚假目标。

您可以使用副本的真实目标,也可以只让它-L完成工作而不用担心 的本地副本libdemo.a

all: program.c
    $(CC) -g -Wall -o $@ $< $(LDFLAGS) $(LIBS)
Run Code Online (Sandbox Code Playgroud)

但话又说回来,你实际上并没有链接到libdemo.a这里的任何地方,所以我不确定你在用它做什么。(要与其链接,您需要或在链接命令中-ldemo列出。)libdemo.a

  • 重新设计得很好,尽管“all”规则仍然直接使用 gcc 而不是 CC 宏。一个小问题。 (3认同)
  • 我很想补充一句“总是安装软件通常不是一个好主意”。特别是对于静态库,从本地重建的副本进行链接非常适合测试。 (3认同)