2017-09-27 42 views
1

我已經閱讀了幾個關於SO的問題,但我的Makefile仍然無法達到我想要的效果。與其他問題相反,我在這裏有一個兩步編譯。步驟如下這些:重新編譯僅更改的文件(兩步)

  • 使用預處理工具(稱爲ppx)產生.cpp.h文件,
  • 然後編譯他們產生.o文件,
  • 最終創建一個動態庫。

所有這些都在Xcode環境(自定義構建目標)內,因此您可以看到所有那些$(TARGET_TEMP_DIR)和類似的變量。

make命令調用其中ppx文件,但我需要放置在正確的目錄中的所有生成的文件(.cpp.h.o.dylib)(見$(LIB))。

注意:ppx工具不保留時間戳

這是我的失敗嘗試:

# target and compiler 
LIB=$(TARGET_TEMP_DIR)/$(TARGET_NAME).dylib 
PPX=$(HOME)/bin/ppx 

# c++ compiler 
CXXFLAGS=-std=c++14 

# files 
PPX_FILES := $(patsubst %.ppx, %.cpp, $(wildcard *.ppx)) 
CPP_FILES := $(patsubst %.ppx, %.o, $(wildcard *.ppx)) 
OBJ_FILES := $(addprefix $(TARGET_TEMP_DIR)/,$(CPP_FILES:%.cpp=%.o)) 

# link library 
all: $(LIB) 

$(LIB): $(PPX_FILES) $(CPP_FILES) $(OBJ_FILES) 
    $(CXX) -dynamiclib -o $(LIB) $(OBJ_FILES) 

# preprocess, generating source and header 
%.cpp: %.ppx 
    $(PPX) -o $(TARGET_TEMP_DIR) $< 

# compile cpp source files 
%.o: %.cpp 
    $(CXX) $(CXXFLAGS) -Ofast -o $(TARGET_TEMP_DIR)/[email protected] -c $(TARGET_TEMP_DIR)/$< 

以上Makefile總是重新編譯所有文件。在閱讀了我在這裏找到的所有問題之後,我成功做的唯一一件事是從不重新編譯Makefile,所以當我更改ppx文件時,它什麼也沒做。

你能幫我發現錯誤嗎?

+0

您的變量「PPX_FILES」和「CPP_FILES」具有誤導性,因爲「PPX_FILES」列出了C++源文件,「CPP_FILES」列出了目標文件。您也不需要從磁盤中爲每個變量獲取文件名,只需替換第一個變量的後綴即可。 –

+0

您的ppx工具是否會重新生成尚未更改的文件?他們的時間戳是否改變? –

+0

@RetiredNinja是的,它的確如此。我試圖用'make'來避免這種情況。 – senseiwa

回答

1

第1步:構建foo.cppfoo.hfoo.ppx,並把它們在正確的目錄。 (我明白你的意思是說, 「正確的目錄」 是$(TARGET_TEMP_DIR),但你是一個有點神祕。)

# preprocess, generating source and header 
$(TARGET_TEMP_DIR)/%.cpp: %.ppx 
    $(PPX) -o $(TARGET_TEMP_DIR) $< 

或更好:

# preprocess, generating source and header 
$(TARGET_TEMP_DIR)/%.cpp: %.ppx 
    $(PPX) -o $(dir [email protected]) $< 

第2步:構建foo.ofoo.cppfoo.h(和bar.hbaz.h,如果需要的話,我建議你接下來看看自動的依賴關係處理。)

# compile cpp source files 
%.o: %.cpp 
    $(CXX) $(CXXFLAGS) -Ofast -o [email protected] -c $< 

第3步:建設所需的目標文件的列表,用理性的名字:

# files          
PPX_FILES := $(wildcard *.ppx) 
OBJ_FILES := $(patsubst %.ppx, $(TARGET_TEMP_DIR)/%.o, $(PPX_FILES)) 

第4步:構建庫:

$(LIB): $(OBJ_FILES) 
    $(CXX) -dynamiclib -o [email protected] $^ 

如果由於時間戳和ppx問題(我不必實驗),它仍然出現故障,然後讓我們知道一條評論;我很確定修復很簡單。

+0

感謝您的回答,它效果很好。我只有一個問題:爲什麼'make'刪除生成的'cpp'文件?我沒有想到。這對我來說很酷,因爲在創建庫之後我不需要它們,但是是否可以刪除'.h'文件? (我已經將它們複製到另一個目錄中) – senseiwa

+1

@senseiwa:認爲'cpp'文件[*中間文件*](https://www.gnu.org/software/make/manual/make.html#Chained -Rules),並在工作完成後將其刪除。刪除頭文件('.h')的最簡單方法是在'$(LIB)'規則中添加'rm -f $(TARGET_TEMP_DIR)/ *。h'命令。 Make可以將它們視爲中間文件,但它很複雜。 – Beta

相關問題