遵循本教程:
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在目录中!
命名您的最终目标,即您的可执行文件:
EXE = hellomake
Run Code Online (Sandbox Code Playgroud)列出您的源和构建输出目录:
SRC_DIR = src
OBJ_DIR = obj
Run Code Online (Sandbox Code Playgroud)列出您的源文件:
SRC = $(wildcard $(SRC_DIR)/*.c)
Run Code Online (Sandbox Code Playgroud)从源文件中,列出目标文件:
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)有一些预处理器标志通过?继续.
CPPFLAGS += -Iinclude # -I is a preprocessor flag, not a compiler flag
Run Code Online (Sandbox Code Playgroud)有一些编译器标志要添加?干得好.
CFLAGS += -Wall # some warnings about bad code
Run Code Online (Sandbox Code Playgroud)有一些链接器标志?
LDFLAGS += -Llib # -L is a linker flag
Run Code Online (Sandbox Code Playgroud)有一些第三方库可以链接?
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)
最后一件事.您应该指示规则何时不使用.PHONY
sepcial规则生成任何目标输出:
.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 定义对我来说似乎没问题,因为它们出现在您的问题中。尝试在文件名之前指定编译器选项:
$(ODIR)/%.o: %.c $(DEPS)
$(CC) $(CFLAGS) -c -o $@ $<
hellomake: $(OBJ)
gcc $(CFLAGS) -o $@ $^
Run Code Online (Sandbox Code Playgroud)
您需要make
从源目录运行。
归档时间: |
|
查看次数: |
13888 次 |
最近记录: |