简单的Makefile问题(具有简单的依赖性)

时间:2009-02-20 07:24:05

标签: c++ unix makefile

我有4个'.cpp'文件和1个头文件:

Tools.cpp
Code1.cpp
Code2.cpp
Code3.cpp

and Tools.hh

现在所有Code1.cpp, Code2.cpp, Code3.cpp 使用Tools.cpp中存储的函数。

目前,我所做的就是使用它来编译它们 这个简单的shell脚本:

#!/bin/bash
echo "compiling Code1.cpp";
g++ Code1.cpp Tools.cpp -o Code1

echo "compiling Code2.cpp";
g++ Code2.cpp Tools.cpp -o Code2 

echo "compiling Code3.cpp";
g++ Code3.cpp Tools.cpp -o Code3

一切正常。

现在我想使用标准的makefile来做到这一点。 但为什么这不起作用:

CXX = g++

TOOLSRC = Tools.cpp Code1.cpp Code2.cpp \
Code3.cpp    

TOOLSINC = Tools.hh      

all: Code1 Code2 Code3

Code1: $(TOOLSRC) $(TOOLSINC) makefile
    $(CXX) $^ -o $@  

Code2: $(TOOLSRC) $(TOOLSINC) makefile
    $(CXX) $^ -o $@  

Code3: $(TOOLSRC) $(TOOLSINC) makefile
    $(CXX) $^ -o $@  

我得到的错误是:

ld: warning in makefile, file is not of required architecture
ld: duplicate symbol neighbors(std::vector<int, std::allocator<int> >&, int, int)in /var/folders/Yx/YxKmmyVPGpakdPL4St7X6++++TI/-Tmp-//ccQCrGHe.o and /var/folders/Yx/YxKmmyVPGpakdPL4St7X6++++TI/-Tmp-//ccreq9YU.o

collect2: ld returned 1 exit status
make: *** [FindNeighbours] Error 1

如何纠正错误?

5 个答案:

答案 0 :(得分:4)

简而言之,$^不是你想要的。它评估“所有先决条件的名称,它们之间有空格”。在问题Makefile中,导致所有三个目标使用几乎相同的命令行,每个命令行看起来像

g++ Tools.cpp Code1.cpp Code2.cpp Code3.cpp Tools.hh makefile -o Code1

从引用的错误消息中,g ++已经决定将makefile作为对象传递给链接器。事实并非如此。如果没有makefile,你仍然会编译和链接所有四个源文件,很可能让链接器决定使用四个main()函数中的哪一个。

您可能希望利用make为常见案例提供大量内置规则的事实。编译两个源文件并将结果链接到这些常见情况。它未经测试,但下面应该做你想要的所有(假设最近构建的gnu make,至少),并且具有仅编译每个对象一次的优势。

all: Code1 Code2 Code3
Code1: Code1.o Tools.o
Code2: Code2.o Tools.o
Code3: Code3.o Tools.o

Code1.o Code2.o Code3.o Tools.o: Tools.hh

如果您需要设置一些编译器选项,您可以添加CXXFLAGS的定义,传统上靠近文件的顶部。

答案 1 :(得分:4)

在这些目标中:

Code1: $(TOOLSRC) $(TOOLSINC) makefile
    $(CXX) $^ -o $@

结果命令为:

g++ Tools.cpp Code1.cpp Code2.cpp Code3.cpp Tools.hh makefile -o Code1

这显然不是你想要的。 g++正在尝试编译头文件和makefile ,并且不知道如何处理makefile 。您还要为每个单元声明所有三个主要单元的依赖关系。因此,如果Code3.cpp发生更改,Code1将需要重新编译。 这也是不受欢迎的。

尝试这样的事情:

CXX = g++

all: Code1 Code2 Code3

%.o: %.cpp
    $(CXX) $(CXXFLAGS) -c -o $@ $^

Code1: Code1.o Tools.o
    $(CXX) -o $@ $^

Code2: Code1.o Tools.o
    $(CXX) -o $@ $^

Code3: Code1.o Tools.o
    $(CXX) -o $@ $^

答案 2 :(得分:2)

嗯。通常,您可以使用“.o”扩展名指定对象文件的依赖项。 Make可能会被混淆,因为它有各种类型文件的内置规则。

错误是因为你试图通过将$ ^传递给编译器来将makefile链接到程序中。

答案 3 :(得分:1)

在规则的右侧,您应该只将 放在有用的文件中。

Code1: Code1.cpp Tools.cpp
    $(CXX) $^ -o $@
Code1: Code2.cpp Tools.cpp
    $(CXX) $^ -o $@
Code3: Code3.cpp Tools.cpp
    $(CXX) $^ -o $@

虽然这可以解决您的问题,但您一定要阅读Grayfade关于如何以“正确的方式”做事的答案。

答案 4 :(得分:0)

我不是makefile的专家,但这就是我通常的做法,而且效果很好。

COMPILER = g++
CXXFLAGS = 
EXECUTABLE = code 

all: code

code: Code1.o Code2.o Code3.o Tools.o
  ${COMPILER} ${CXXFLAGS} -o ${EXECUTABLE} Code1.o Code2.o Code3.o Tools.o

Code1.o: Code1.cpp Tools.o
  ${COMPILER} ${CXXFLAGS} -c Code1.cpp

Code2.o: Code2.cpp Tools.o
  ${COMPILER} ${CXXFLAGS} -c Code2.cpp

Code3.o: Code3.cpp Tools.o
  ${COMPILER} ${CXXFLAGS} -c Code3.cpp

Tools.o: Tools.cpp Tools.hh
  ${COMPILER} ${CXXFLAGS} -c Tools.cpp

clean:
  rm *.o
  rm ${EXECUTABLE}