2009-02-20 81 views
1

我有4 '的.cpp' 文件和1個文件:簡單的makefile問題(用一個簡單的依賴性)

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 [email protected] 

Code2: $(TOOLSRC) $(TOOLSINC) makefile 
    $(CXX) $^ -o [email protected] 

Code3: $(TOOLSRC) $(TOOLSINC) makefile 
    $(CXX) $^ -o [email protected] 

我得到的錯誤是這樣的:

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 

我怎樣才能糾正錯誤?

回答

4

在這些目標:

Code1: $(TOOLSRC) $(TOOLSINC) makefile 
    $(CXX) $^ -o [email protected] 

得到的命令是:

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

這顯然不是你想要的。g++正在嘗試編譯頭文件和生成文件,並不知道如何處理生成文件。你還要聲明每個單元的所有三個主單元的相關性。所以如果Code3.cpp發生變化Code​​1將需要重新編譯。 這也是不可取的。

嘗試這樣代替:

CXX = g++ 

all: Code1 Code2 Code3 

%.o: %.cpp 
    $(CXX) $(CXXFLAGS) -c -o [email protected] $^ 

Code1: Code1.o Tools.o 
    $(CXX) -o [email protected] $^ 

Code2: Code1.o Tools.o 
    $(CXX) -o [email protected] $^ 

Code3: Code1.o Tools.o 
    $(CXX) -o [email protected] $^ 
2

嗯。通常你會用「.o」擴展名指定對象文件的依賴關係。 Make可能會讓人感到困惑,因爲它內置了各種類型文件的規則。

錯誤是因爲您想通過將$ ^傳遞給編譯器來將makefile鏈接到程序中。

+0

嗨,有什麼替代$ ^呢? – neversaint 2009-02-20 07:38:18

+0

你不應該需要任何東西,make應該能夠推導出自己的構建命令。或者按照greyfade的建議做,不依賴於makefile。 – unwind 2009-02-20 07:56:39

1

在規則的右側,你應該把只有這些文件是有用的。

Code1: Code1.cpp Tools.cpp 
    $(CXX) $^ -o [email protected] 
Code1: Code2.cpp Tools.cpp 
    $(CXX) $^ -o [email protected] 
Code3: Code3.cpp Tools.cpp 
    $(CXX) $^ -o [email protected] 

雖然這解決了您的問題,但您應該閱讀Grayfade關於如何做「正確方法」的答案。

+0

這將使編譯器不止一次地處理tools.cpp - 這是不必要的。請參閱下面的Greyfade以獲取更好的解釋,Rberteig更短的makefile。 – nimrodm 2009-02-20 08:21:06

4

總之,$^不是你想要的。它評估爲「所有先決條件的名稱,它們之間有空格」。在問題生成文件,導致所有三個目標使用幾乎相同的命令線,使得每個像

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

從援引該錯誤消息,克++已決定,生成文件應該被傳遞到鏈接器就好像它是一個目的。事實並非如此。如果沒有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添加一個定義。

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}