path include和src目录下的makefile

iBe*_*wer 5 c c++ makefile

遵循本教程:

http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/

它有3个文件,其中2个是.c文件,1个.h文件.本教程是关于设置makefile的,前几步是有效的.最后一步涉及为.h.c文件设置目录路径.我已将.c文件放在src文件中,并将.h文件放在包含文件中.

它看起来像/home/bob/testcode/src< - 包含.c文件.

并且/home/bob/testcode/include< - 包含.h文件.

码:

IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)

ODIR=obj
LDIR =../lib

_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))

_OBJ = hellomake.o hellofunc.o 
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))


$(ODIR)/%.o: %.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS)

hellomake: $(OBJ)
    gcc -o $@ $^ $(CFLAGS)

.PHONY: clean

clean:
    rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 
Run Code Online (Sandbox Code Playgroud)

我想了解它是如何工作的,然后在我正在使用的库上使用它.有人可以指点我如何设置此代码?我已经尝试了很多选择"/home/bob/testcode/include/"W /和W/O "/我还没有得到它的工作.

目标是使用包含60多个头文件和30个源文件的库,从这些文件中我必须运行1个main,所以我真的需要让这个基本的makefile工作,所以我可以扩展它.

一般的问题是这些线路是敞开的:

IDIR =../include
Run Code Online (Sandbox Code Playgroud)
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
Run Code Online (Sandbox Code Playgroud)

OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
Run Code Online (Sandbox Code Playgroud)

为此,我尝试了许多不同的路径替换,但我生成的错误说:

gcc -o hellomake  -I../include
gcc: fatal error: no input files
compilation terminated.
make: *** [hellomake] Error 4
Run Code Online (Sandbox Code Playgroud)

请提前帮助,谢谢.

Chn*_*sos 35

你的教程推广不良做法,你应该避免它恕我直言.

在你的规则中:

$(ODIR)/%.o: %.c $(DEPS)
Run Code Online (Sandbox Code Playgroud)

当你的源文件在src目录中时,你告诉make查看当前目录,因此从未使用过这种模式而你没有合适的模式.


确保按如下方式组织项目目录:

+ include/
|-- all .h files here
+ lib/
|-- all thirdparty library files (.a files) here
+ obj/
|-- all .o files will be placed here
+ src/
|-- all .c files here
+ Makefile
Run Code Online (Sandbox Code Playgroud)

然后让我们使用良好实践逐步完成该过程.

首先,如果您不需要,请不要定义任何内容.Make有很多预定义的变量和函数,在尝试手动执行之前应该使用它们.事实上,他有这么多,你可以编译一个简单的项目,甚至根本没有Makefile在目录中!

  1. 命名您的最终目标,即您的可执行文件:

    EXE = hellomake
    
    Run Code Online (Sandbox Code Playgroud)
  2. 列出您的源和构建输出目录:

    SRC_DIR = src
    OBJ_DIR = obj
    
    Run Code Online (Sandbox Code Playgroud)
  3. 列出您的源文件:

    SRC = $(wildcard $(SRC_DIR)/*.c)
    
    Run Code Online (Sandbox Code Playgroud)
  4. 从源文件中,列出目标文件:

    OBJ = $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) # patsubst is far less readable
    # You can also do it like that
    OBJ = $(addprefix $(OBJ_DIR)/, $(notdir $(SRC)))
    
    Run Code Online (Sandbox Code Playgroud)
  5. 有一些预处理器标志通过?继续.

    CPPFLAGS += -Iinclude # -I is a preprocessor flag, not a compiler flag
    
    Run Code Online (Sandbox Code Playgroud)
  6. 有一些编译器标志要添加?干得好.

    CFLAGS += -Wall # some warnings about bad code
    
    Run Code Online (Sandbox Code Playgroud)
  7. 有一些链接器标志?

    LDFLAGS += -Llib # -L is a linker flag
    
    Run Code Online (Sandbox Code Playgroud)
  8. 有一些第三方库可以链接?

    LDLIBS += -lm # Left empty if no libs are needed
    
    Run Code Online (Sandbox Code Playgroud)

好了,现在我们已经正确地填充了一些食谱.

广泛传播的是应该调用默认目标all.为简单起见,它应该是Makefile中的第一个目标,它的先决条件应该是您make在命令行上编写时要构建的目标:

all: $(EXE)
Run Code Online (Sandbox Code Playgroud)

现在列出构建可执行文件的先决条件,并填写其配方以告知如何处理这些:

$(EXE): $(OBJ)
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
Run Code Online (Sandbox Code Playgroud)

一些快速说明:

  • $(CC) 是一个内置变量,已包含在C中编译和链接时所需的内容,
  • 为了避免链接器错误,您应该放在目标文件$(LDFLAGS) 之前$(LDLIBS) 之后.
  • $(CPPFLAGS)并且$(CFLAGS)没用这里,编译阶段已经结束,它是这里的链接阶段.

下一步,由于您的源文件和目标文件不共享相同的前缀,因此您需要告诉make要做什么,因为其内置规则不包括您的特定情况:

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
Run Code Online (Sandbox Code Playgroud)

好的,现在可执行文件应该很好地构建,如果需要,我们可以清理构建目录:

clean:
    $(RM) $(OBJ)
Run Code Online (Sandbox Code Playgroud)

最后一件事.您应该指示规则何时不使用.PHONYsepcial规则生成任何目标输出:

.PHONY: all clean
Run Code Online (Sandbox Code Playgroud)

最后结果:

EXE = hellomake

SRC_DIR = src
OBJ_DIR = obj

SRC = $(wildcard $(SRC_DIR)/*.c)
OBJ = $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)

CPPFLAGS += -Iinclude
CFLAGS += -Wall
LDFLAGS += -Llib
LDLIBS += -lm

.PHONY: all clean

all: $(EXE)

$(EXE): $(OBJ)
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@

clean:
    $(RM) $(OBJ)
Run Code Online (Sandbox Code Playgroud)

  • makefile 需要制表符,而不是空格。请注意,从这里复制时。 (7认同)
  • 谢谢!关于如何编写 makefile 的写得很好的介绍 :-) (2认同)

chq*_*lie 0

简单的 Makefile 定义对我来说似乎没问题,因为它们出现在您的问题中。尝试在文件名之前指定编译器选项:

$(ODIR)/%.o: %.c $(DEPS)
    $(CC) $(CFLAGS) -c -o $@ $<

hellomake: $(OBJ)
    gcc $(CFLAGS) -o $@ $^
Run Code Online (Sandbox Code Playgroud)

您需要make从源目录运行。