Makefile在Windows和Linux下处理不同的源和目标目录

时间:2015-03-04 18:03:01

标签: c++ linux windows makefile

我在为源项目分散在不同文件夹中的项目创建Makefile时遇到问题。由于源文件可能具有相同的名称,我也希望将对象发送到不同的文件夹中。使用单个源文件和目标文件,我可以遵循其他地方(Automatic makefile with source and object files in different directories)发布的规则。 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 obj\main.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..\minime_pp\src\minime_class.cpp -o obj\minime_pp\minime_class.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..\minime_pp\src\minime_class.cpp -o obj\minime_pp\fifo_class.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..\minime_pp\src\minime_class.cpp -o obj\minime_pp\fit_fun.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..\minime_pp\src\minime_class.cpp -o obj\minime_pp\funcs.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..\minime_pp\src\minime_class.cpp -o obj\minime_pp\gabe_class.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..\minime_pp\src\minime_class.cpp -o obj\minime_pp\minimizer_s.o
g++ -O0 -g -Wall -Wextra -pedantic -std=c++11 -fopenmp -c ..\minime_pp\src\minime_class.cpp -o obj\minime_pp\random.o

原因是-c $<语法只接受依赖项的第一个条目(在本例中为..\minime_pp\src\minime_class.cpp)。

解决方法可能是切换回像

这样的定义
$(MINIME_ODIR)/%.o: $(MINIME_SDIR)/%.cpp
    $(CXX) $(CFLAGS) -c $< -o $@

现在的问题是反斜杠 - $(OBJECTS_ALL)中没有要求匹配这个新定义,因此没有任何反应。在定义中使用\将无法正常工作。所以我认为你摆脱了反斜杠 - 正斜杠转换,但随后自动目录创建不能在Windows上工作。类似于-c $<,但$<选择匹配的&#39;没有/%.cpp的列表中的一个基本上是我正在寻找的。

如果有人知道编写两个Makefile(Windows,Linux)的方法感谢提示。

1 个答案:

答案 0 :(得分:1)

绝不应在makefile中使用反斜杠分隔符。几乎所有Windows工具都支持普通的UNIX斜杠作为目录分隔符。对于那些没有的人来说,更容易将它们转换为配方中的特定实用程序:换句话说,仅在需要的地方将调用放入配方中。

请注意,几乎没有失败的是需要反斜杠的命令将是Windows特定的(command.com)命令,无论如何都无法移植到UNIX。