Makefile在Windows和Linux下处理不同的源目录和对象目录
Makefile dealing with different source and object directories under Windows and Linux
我在为一个源文件分散在不同文件夹中的项目创建Makefile时遇到问题。由于源文件可能具有相同的名称,我也想将对象发送到不同的文件夹中。对于单个源文件和对象文件,我可以很好地遵循其他地方发布的规则(在不同目录中使用源文件和目标文件的自动生成文件)。Makefile必须足以与Windows和Linux一起使用,我通过pathfix
定义来解决这个问题(请参阅下面的代码)。这部分做得不错,但我可能会忽略一些细节。以下是Makefile的缩短版本,展示了我的方法:
CXX = g++
CFLAGS = -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp
FILES = main.cpp
FILES_MINIME = minime_class.cpp fifo_class.cpp fit_fun.cpp funcs.cpp gabe_class.cpp minimizer_s.cpp random.cpp
# check the OS
ifdef windir
binfix = .exe
pathfix = $(subst /,,$1)
OSID = 1
else
ifeq ($(shell uname), Linux)
binfix =
pathfix = $1
OSID = 0
else
ifneq ($(shell uname), Linux)
$(error OS not identified)
endif
endif
endif
# define the different paths of objects and sources
ODIR = obj
SDIR = .
MINIME_SDIR = $(call pathfix, ../minime_pp/src)
MINIME_ODIR = $(call pathfix, obj/minime_pp)
# create templates for the objects by replacing the cpp with an o
_OBJECTS = $(patsubst %.cpp, %.o, $(FILES))
_OBJECTS_MINIME = $(patsubst %.cpp, %.o, $(FILES_MINIME))
# combine the source- and the file names
SOURCE_MINIME = $(call pathfix, $(addprefix $(MINIME_SDIR)/, $(FILES_MINIME)))
# now combine the object- and the file names
OBJECTS = $(call pathfix, $(addprefix $(ODIR)/, $(_OBJECTS)))
OBJECTS_MINIME = $(call pathfix, $(addprefix $(MINIME_ODIR)/, $(_OBJECTS_MINIME)))
# add upp all the objects
OBJECTS_ALL = $(OBJECTS) $(OBJECTS_MINIME)
# define the rules
$(PROJECT): $(OBJECTS_ALL)
$(CXX) -o $@$(binfix) $^
$(OBJECTS): $(FILES) Makefile
$(CXX) $(CFLAGS) -c $< -o $@
$(OBJECTS_MINIME): $(SOURCE_MINIME)
$(CXX) $(CFLAGS) -c $< -o $@
# create the folders (if necessary)
$(OBJECTS): | $(ODIR)
$(OBJECTS_MINIME): | $(MINIME_ODIR)
$(ODIR):
mkdir $(ODIR)
$(MINIME_ODIR):
mkdir $(MINIME_ODIR)
这个问题在输出中最容易说明。在Windows上,mingw32-make > output.txt
读取
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c main.cpp -o objmain.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..minime_ppsrcminime_class.cpp -o objminime_ppminime_class.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..minime_ppsrcminime_class.cpp -o objminime_ppfifo_class.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..minime_ppsrcminime_class.cpp -o objminime_ppfit_fun.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..minime_ppsrcminime_class.cpp -o objminime_ppfuncs.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..minime_ppsrcminime_class.cpp -o objminime_ppgabe_class.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..minime_ppsrcminime_class.cpp -o objminime_ppminimizer_s.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..minime_ppsrcminime_class.cpp -o objminime_pprandom.o
其原因是-c $<
语法只获取依赖项的第一个条目(在本例中为..minime_ppsrcminime_class.cpp
)。
对此的解决方案可能是切换回类似的定义
$(MINIME_ODIR)/%.o: $(MINIME_SDIR)/%.cpp
$(CXX) $(CFLAGS) -c $< -o $@
现在的问题是反斜杠——$(OBJECTS_ALL)
中没有与这个新定义匹配的要求,因此不会发生任何事情。在定义中使用是行不通的。所以我认为你可以去掉反斜杠-正斜杠转换,但自动创建目录在Windows上不起作用。类似于
-c $<
,但有了$<
,从没有/%.cpp
的列表中选择"匹配"的基本上就是我想要的。
如果有人知道如何编写两个Makefile(Windows、Linux),感谢您的提示。
您不应该在makefile中使用反斜杠分隔符。几乎所有的Windows工具都支持普通的UNIX斜线作为目录分隔符。对于那些没有的少数人来说,将它们转换为食谱中的特定实用程序更容易:换句话说,只在需要的地方将对$(pathfix ...)
的调用放在食谱中。
请注意,几乎毫无疑问,需要反斜杠的命令将是特定于Windows的(command.com)命令,无论如何都不能移植到UNIX。
我这样做是为了让Windows和Linux/MacOS:都有相同的makefile
ifeq ($(OS),Windows_NT)
RM = del /Q /F
RRM = rmdir /Q /S
mkdirp = mkdir $(subst /,,$1)
else
RM = rm -f
RRM = rm -rf
mkdirp = mkdir -p $1
endif
$(BUILDDIR):
$(call mkdirp, $@)
clean:
-$(RRM) $(BUILDDIR)
-$(RM) $(TARGET)
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 如何使用对C函数和类对象的外部调用来处理C++头文件
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 使用对象数组对 SFML 进行动画处理
- CPU 瓶颈;处理具有许多非静态对象的 3D 场景渲染的简单方法
- 使用对象的基类部分模板专用化对对象进行哈希处理::哈希
- C++:处理线程本地对象销毁
- 传递多处理.将对象值为 ctype 函数?
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 使用返回对象的函数处理错误
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- 处理从列表中删除指向对象的指针的"healthy"方法是什么?
- C++如何处理同名对象的向量?
- static是如何使用ClassA::m_variable处理所有类对象的
- 当线程处理不同的类时,应该在哪里声明条件变量、互斥对象
- 处理无法按预期方式创建的对象,c++
- 我可以将类作为C 中的对象处理
- QT良好的全局变量/对象处理
- 如何将map和unordered_map作为同一对象处理
- 强制一个对象处理输入的信号