簡體   English   中英

Makefile 標記依賴、編譯和鏈接

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM