c - 为内部目录创建目标文件时makefile失败
问题描述
在当前目录中,我有以下文件:
election.c election.h extended_map.c extended_map.h main.c test_utilities.c utilities.c utilities.h
另外,我在当前文件夹中有一个内部文件夹,mtm_map
其中包括map.c map.h
我创建了一个运行良好的makefile:
make main.o
make extended_map.o
make election.o
make utilities.o
make clean
但运行时失败:
-bash-4.2$ make map.o
cc -c -o map.o map.c
map.c: In function ‘getIndexOfKey’:
map.c:36:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int i = 0; i < map->size; i++)
^
map.c:36:5: note: use option -std=c99 or -std=gnu99 to compile your code
map.c: In function ‘initializeElements’:
map.c:59:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int i=initial_index;i<last_index;i++)
^
map.c: In function ‘mapCopy’:
map.c:165:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int i = 0; i < map->size; i++)
^
map.c: In function ‘mapGet’:
map.c:239:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int i = 0; i < map->size; i++)
^
make: *** [map.o] Error 1
生成文件:
CC = gcc
OBJS = main.o ./mtm_map/map.o extended_map.o election.o utilities.o
EXEC = election
DEBUG_FLAG = -DNDEBUG
COMP_FLAG = -std=c99 -Wall -pedantic-errors -Werror
$(EXEC) : $(OBJS)
$(CC) $(DEBUG_FLAG) $(OBJS) -o $@
main.o: main.c ./mtm_map/map.h election.h test_utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
map.o: ./mtm_map/map.c ./mtm_map/map.h utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
extended_map.o: extended_map.c extended_map.h ./mtm_map/map.h utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
election.o: election.c election.h ./mtm_map/map.h extended_map.h utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
utilities.o: utilities.c utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
clean:
rm -f $(OBJS) $(EXEC)
关于如何解决这个问题的任何建议?请注意,我希望在当前目录中创建 map.o(不是在里面mtm_map
)
解决方案
您的 Make 没有正确使用$(COMP_FLAG)
您在其中定义的内容:
通常有一个CFLAGS
变量可以使用隐式规则来编译源文件,所以我会重写你Makefile
的,以消除你包含在其中的大量冗余代码:
# I use the ?= operator, so you can redefine the compiler with make CC=clang ...
CC ?= gcc
EXEC = election
TOCLEAN = $(EXEC)
# NDEBUG is a compilation option, not a linking one. The purpose of MY_CFLAGS is
# to allow you to define extra CFLAGS to be used on source code compilation.
CFLAGS = -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG $(MY_CFLAGS)
OBJS = main.o mtm_map/map.o extended_map.o election.o utilities.o
# you can add files to clean in a more complex makefile
TOCLEAN += $(OBJS)
$(EXEC): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
clean:
rm -f $(TOCLEAN)
# Extra dependencies (the dependency a.o : a.c is automatic)
main.o: mtm_map/map.h election.h utilities.h
mtm_map/map.o: mtm_map/map.h utilities.h
extended_map.o: extended_map.h mtm_map/map.h utilities.h
election.o: election.h mtm_map/map.h extended_map.h utilities.h
utilities.o: utilities.h
这应该正确构建您的项目。
笔记
如果您决定某些源文件必须驻留在您拥有 Makefile 的目录之外的其他目录中,那么您必须考虑是否要将目标文件放在您的目录中或源文件所在的目录中。我遵循了我认为您想要的内容(在此目录中构建所有源文件可能会导致名称冲突,因为不同目录中的两个文件可以具有相同的名称)但是您还必须使用对象的路径(如我这里用过)
还有另一种选择,是创建一个构建目录,因此所有文件都构建在副本或源中使用的层次结构中。但这还有其他一些缺点,因为您必须重写自动规则,以便在尝试将文件放入其中之前重建您拥有的目录结构。
推荐阅读
- python - pandas 数据帧是如何存储在内存中的?
- android - 在一个活动中初始化的 Kotlin (android studio) 中的全局变量在其他活动中保持初始化值
- spring-boot - 使用 MockMvc 自定义 Spring 安全过滤器测试总是返回 404
- javascript - 双引号和 JSON.stringify
- azure-devops - 限制用户从 Azure DevOps 访问 Board
- spring-boot - 规避 Boostrap-Table 缓慢渲染 100 多行
- c# - Indexer Initializer 的 VB.Net 等效项
- node.js - 如何使用环境变量隐藏客户端代码的秘密?
- unity3d - 将 DLL 导入统一时遇到问题
- php - 属于投掷试图获取非对象的属性“jenis_bahan”