2017-10-12 41 views
0

我在這裏有一個簡單的makefile。這是一個最小的C++項目,我希望使用隱式規則來做正確的行爲。 與下面的makefile,它會報告錯誤。然後我輸入「make -n」,似乎make使用cc而不是cxx。 但是,當我檢查了GNU頁面時,它說CXX是一個隱含變量: https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html如何才能推斷出最終目標需要哪種編譯器?

所以我可以說最終目標。隱式工具總是cc?

objects = test.o main.o 
CXX=g++ 
CFLAGS=-std=c++11 

test: $(objects) 

.PHONY: clean 
clean: 
    rm -f *.o test 
+2

用於鏈接的命令在'LD'變量中。您需要將其設置爲正確的前端程序(即'g ++')。 –

+0

@Someprogrammerdude thnx的信息。我編輯了我的標題,我認爲這有點誤導。我的意思是別的。 –

+0

不相關,但您應該嘗試使用[CMake](http://www.cmake.org),我覺得它更優雅,使用更簡單。 – vsoftco

回答

1

這可能是因爲你的目標文件正在與製作的默認鏈接,這是$(CC)連接。我們可以看到,如果我們的make --print-data-base -f /dev/null輸出看 - 特別是:

%: %.o 
# recipe to execute (built-in): 
     $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o [email protected] 

如果我們看一下LINK.o定義,我們可以看到:

# default 
LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH) 

幸運的是,Make爲我們提供了LINK.cc

# default 
LINK.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) 

所以我們需要做的是重新定義LINK.o是的LINK.cc的價值,並且連接將通過我們的C++編譯器來完成:

LINK.o = $(LINK.cc) 

如果我們有幾個目標,我們可以使用一個目標因變量來定位效果:

test: LINK.o = $(LINK.cc) 

在Makefile文件的其他評論:

  • test是程序中的可憐的名字 - 很容易錯誤地運行標準/usr/bin/test
  • 您可能指的是CXXFLAGS=-std=c++11(而不是CFLAGS)。
  • 所有makefile應包含一個.DELETE_ON_ERROR:目標,以便中斷的命令不會保留最新顯示的部分輸出。
+0

Thnx的解釋。所以我認爲make也可以確定它需要哪個鏈接器來實現正確的行爲,例如C++或c。所以它似乎使用cc的所有.o文件來鏈接它們?所以這一步我不能使用除c項目之外的隱式變量。 –

+0

Make使用文件名來確定(例如)'%.cpp'→'%.o'需要C++編譯器。同樣,如果您只有一個源文件,則可將C++源代碼直接轉換爲可執行文件。但是,一旦你有了目標文件,它只有一條鏈接它們的規則 - 這可能適用於C,Fortran或者Pascal,並且它可以適用於C++(但是隻有當你明白用'g ++'鏈接時最少)標準C++庫,並且您手動將必要的標誌添加到'LDLIBS')。設置'LINK.o',IMO更容易。 –

相關問題