如何制作用于创建库和输出文件的 makefile?

时间:2021-02-23 10:33:57

标签: c linux makefile

我想在 lib 中制作一个库文件并在 bin 目录中制作输出文件。 但是我的 makefile 不起作用。

我的目录树
~/home$ 树

.
├── bin
├── include
│   └── myhead.h
├── lib
├── libsrc
│   └── myfunc.c
└── src
    ├── Makefile
    └── main.c

这是我的makefile

.SUFFIXES = .c .o
.c.o :
        $(CC) $(INC) $(CFLAGS) $<


CC = gcc
CFLAGS = -g -c
AR = ar
OBJECTS = main.o
SRCS = main.c

LIB_TARGET = ../lib/libmyfunc.a
LIB_OBJS = ../libsrc/myfunc.o
LIB_SRCS = ../libsrc/myfunc.c

LIBS = -lmyfunc
LIB_DIR = -L../lib

$(LIB_TARGET) : $(LIB_OBJS)
        $(AR) -rcv  $(LIB_TARGET) $(LIB_OBJS)

INC = -I../include

TARGET = ../bin/main

$(TARGET) : $(OBJECTS)
        $(CC) -o $(TARGET) $(OBJECTS) $(LIB_DIR) $(LIBS)

clean :
        rm -rf $(OBJECTS) $(TARGET) core

我认为它有效,但它不起作用。 我得到一个 ar: ../libsrc/myfunc.o: No such file or directory 错误 以及在 src 目录中创建的 myfunc.o 文件。

我想获得类似的文件

.
├── bin
│   └── main.out    <-- new
├── include
│   └── myhead.h
├── lib
│   └── libmyfunc.a  <-- new
├── libsrc
│   └── myfunc.c
│   └── myfunc.o    <-- new
└── src
    ├── Makefile
    └── main.c

编辑:

我的构建日志

~/home/src$ make
gcc -I../include -g -c ../libsrc/myfunc.c
ar -rcv  ../lib/libmyfunc.a ../libsrc/myfunc.o
ar: ../libsrc/myfunc.o: No such file or directory
make: *** [Makefile:20: ../lib/libmyfunc.a] Error 1

建造后的树
~/home$ 树

.
├── bin
├── include
│   └── myhead.h
├── lib
├── libsrc
│   └── myfunc.c
└── src
    ├── Makefile
    ├── main.c
    └── myfunc.o

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

请注意,此论坛使用 Tab 缩进,因此如果您复制粘贴以下 Makefile,请使用例如修复缩进sed -e 's|^ *|\t|' -i Makefile .

我会使用

LIBSRC  := libsrc
LIBDIR  := lib
BINSRC  := src
BINDIR  := bin
INCDIR  := include
CC      := gcc
CFLAGS  := -Wall -Wextra -O2
LDFLAGS :=
TARGETS := $(BINDIR)/main.out $(LIBDIR)/libmyfunc.a
LIBOBJS := $(LIBSRC)/myfunc.o

.PHONY: all clean
all: $(TARGETS)

clean:
        rm -f $(TARGETS) $(BINSRC)/*.o $(LIBSRC)/*.o

$(LIBSRC)/%.o: $(LIBSRC)/%.c
        $(CC) $(CFLAGS) -I$(INCDIR) $(LDFLAGS) -c $^ -o $@

$(BINSRC)/%.o: $(BINSRC)/%.c
        $(CC) $(CFLAGS) -I$(INCDIR) $(LDFLAGS) -c $^ -o $@

$(LIBDIR)/libmyfunc.a: $(LIBOBJS)
        $(AR) -rcv $@ $^

$(BINDIR)/main.out: $(BINSRC)/main.o $(LIBDIR)/libmyfunc.a
        $(CC) $(CFLAGS) -I$(INCDIR)/ $(BINSRC)/main.o $(LDFLAGS) -L$(LIBDIR) -lmyfunc -o $@

或者,如果您更喜欢将临时目标文件放在一个单独的目录中,比如 build/,那么

CC       := gcc
CFLAGS   := -Wall -Wextra -O2
LDFLAGS  :=

BUILDDIR := build

INCDIR   := include
SRCDIR   := src
BINDIR   := bin
LIBDIR   := lib

MAINOBJS := $(BUILDDIR)/main.o
LIBOBJS  := $(BUILDDIR)/myfunc.o
TARGETS  := $(BINDIR)/main $(LIBDIR)/libmyfunc.a

.PHONY: all clean

all: $(TARGETS)

clean:
        rm -f $(TARGETS) $(MAINOBJS) $(LIBOBJS) $(BUILDDIR)/*

$(LIBDIR)/libmyfunc.a: $(LIBOBJS)
        $(AR) -rcv $@ $(LIBOBJS)

$(BUILDDIR)/%.o: $(SRCDIR)/%.c
        $(CC) $(CFLAGS) -I$(INCDIR) -c $^ -o $@

$(BINDIR)/main: $(MAINOBJS) $(LIBDIR)/libmyfunc.a
        $(CC) $(CFLAGS) -I$(INCDIR) $(MAINOBJS) $(LDFLAGS) -L$(LIBDIR) -lmyfunc -o $@

这样做的好处是可以保持源目录不变。