[英]Makefile Mark Dependency, Compile and Link
我有一個在 openmp 中完成的障礙的模塊化實現。 我有一個我想鏈接的測試工具。 該目錄如下所示:
Project/
-Tests
-openmp_tournament
-test_openmp_tournament.cpp
-OpenMP
-tournament.cpp . //barrier implementation
-tournament.h
現在,兩個 .cpp 文件在 Project/OpenMp/ 中都有一個包含為比賽.h 的頭文件。 這個想法是編譯兩者,然后以模塊化方式將它們鏈接在一起(因為我有各種要測試的實現)。 我的生成文件如下所示:
PATH_TO_OPENMP = ../../OpenMP/
#OpenMP Flags Etc.
OMPFLAGS = -fopenmp -DLEVEL1_DCACHE_LINESIZE=`getconf LEVEL1_DCACHE_LINESIZE`
OMPLIBS = -lgomp
CC = g++
CPPFLAGS = -MMD -MP # enables automatic dependency tracking
CFLAGS = -Wall -Wextra -I$(PATH_TO_OPENMP) $(OMPFLAGS) -std=c++11
LDLIBS = $(OMPLIBS)
COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDLIBS) -o $@
COMPILE_NOLINK = $(CC) -c $(CPPFLAGS) $(CFLAGS) $< $(LDLIBS) -o $@
all: tournament_openmp.a
# link all files into one binary
tournament_openmp.a: tournament.o test_openmp_tournament.o
$(COMPILE)
# compile only each source file and mark as dependent
%.o: $(PATH_TO_OPENMP)%.cpp %.d
$(COMPILE_NOLINK)
# Empty pattern rule to match dependency (*.d) files (i.e. makefiles),
# so make won't fail if dependency doesn't exist
%.d: ;
# Mark dependency files as precious so they won't be deleted as intermediates
.PRECIOUS: %.d
# The list of all source files I want to track dependencies for
SOURCES=$(wildcard *.cpp)
# Include any dependency files that exist, and
# suppress error message for ones that don't yet (via hyphen)
-include $(SOURCES:.cpp=.d)
.PHONY: clean
clean:
rm -rf *.o *.d *.a *_openmp *_mpi
當我運行 Make 時,出現以下錯誤,我不確定如何解決它。 它找不到 test_openmp_tournament.cpp 文件的錦標賽.h:
a@ubuntu:~/Documents/Project/Tests/openmp_tournament$ make all
g++ -c -MMD -MP -Wall -Wextra -I../../OpenMP/ -fopenmp -DLEVEL1_DCACHE_LINESIZE=`getconf LEVEL1_DCACHE_LINESIZE` -std=c++11 ../../OpenMP/tournament.cpp -lgomp -o tournament.o
g++ -MMD -MP -c -o test_openmp_tournament.o test_openmp_tournament.cpp
test_openmp_tournament.cpp:51:10: fatal error: tournament.h: No such file or directory
51 | #include "tournament.h"
為什么編譯器找不到你的頭文件? 好吧,我們應該始終假設編譯器是正確的,而您做錯了 :)。 所以,看看有效的編譯行:
g++ -c -MMD -MP -Wall -Wextra -I../../OpenMP/ -fopenmp ...
那么失敗的那個:
g++ -MMD -MP -c ...
很明顯為什么編譯器找不到你的頭文件,對吧? 因為,你沒有給它正確的編譯器標志。
那么問題來了,為什么 make 不運行我們期望的編譯命令呢? make 這樣做的唯一原因是它使用兩個不同的規則來構建兩個目標。 那么讓我們來看看你的規則:
%.o: $(PATH_TO_OPENMP)%.cpp %.d
$(COMPILE_NOLINK)
好吧,這告訴 make 如何從文件../../OpenMP/xxx.cpp
為任何xxx
構建文件xxx.o
。 這對../../OpenMP
目錄中的源文件../../OpenMP
,但當然這個規則不能用於構建../../OpenMP
沒有源文件的任何目標文件。
那么,如果您的規則不匹配,該怎么辦? 它將查看自己的內置規則,果然,有一個內置規則知道如何從當前目錄中的源文件構建目標文件。
為什么這會失敗? 它失敗是因為您使用的是非標准變量,因此 make 使用的內置規則沒有使用您的自定義變量。
特別是, CPPFLAGS
變量旨在保存 C/C++ 預處理器標志,因此從技術上講-I
選項(這是一個預處理器選項)應該出現在該變量中。 其次,C++ 編譯器的標准變量是CXX
用於編譯器(不是CC
,它是 C 編譯器)和CXXFLAGS
是標志(不是CFLAGS
,它是用於 C 編譯器)。
因此,您應該至少執行以下一項操作,也可能同時執行兩項操作:
將您的變量名稱修復為標准名稱:
CXX = g++
CPPFLAGS = -MMD -MP -I$(PATH_TO_OPENMP)
CXXFLAGS = -Wall -Wextra $(OMPFLAGS) -std=c++11
創建一個規則來構建本地對象而不是默認規則:
%.o: %.cpp %.d
$(COMPILE_NOLINK)
(精明會注意到OMPFLAGS
包含在其中的預處理標志以及:在-D
選項...你是否想嘗試取笑說出來它是不是由你)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.