[英]Makefile working in Linux but not under Windows, can't find files in subdirectory
我有一個在Linux下工作的makefile(gnu make),但是將其移植到Windows時不起作用。 makefile的目標是制作所有位於不同子目錄中的* .cpp文件,並將它們編譯為單個BUILD_DIR中的* .obj文件。
在linux和Windows之間,我僅調整了SOURCES變量,顯示了linux行,但已注釋。 當我檢查所有名稱和目錄時,它們顯示相同的內容(它們在透視符號中的相對路徑)和我期望的內容。
我在Windows上收到的“錯誤消息”是:make:***沒有規則來創建目標“ DEM.cpp”,這是“ DEM.obj”所需的。 停止。
在調試模式下,它說:文件'DEM.cpp'不存在。 (顯然是這樣)
在linux上,它通過VPATH查找文件,在調試模式下,它說:無需重新制作目標文件'DEM.cpp'; 使用VPATH名稱“ ./Code/DEM.cpp”。
linux和Windows中的子目錄結構相同,並且makefile從相同的位置運行。
問題:這里出了什么問題,我感覺這與在Windows上以不同方式處理VPATH有關,但我不確定。
我的makefile是:
# MAKEFILE
# Some makefile settings
SHELL = /bin/sh #Make sure the shell is the standard shell
.SUFFIXES: #Clear al implicit suffixes
.SUFFIXES: .cpp .obj #Set used suffixes
# Variable Declaration
CXX := g++
BUILD_DIR = .\bin\Release
PROGRAM_NAME := DEM.exe
#SOURCES := $(shell find . -name '*.cpp') #All *.cpp files with directory (LINUX style)
SOURCES := $(shell FORFILES /S /M *.cpp /C "CMD /C ECHO @relpath") #All *.cpp files with directory
NAMES := $(notdir $(basename $(SOURCES))) #Get all files names of the *.cpp files without extensions
OBJECTS := $(addsuffix .obj, $(NAMES)) #Get the to be generate *.o files without directory
SRC_DIRS := $(dir $(SOURCES)) #All the directory in which the sources are found
VPATH := $(SRC_DIRS) $(BUILD_DIR)
.PHONY: all
all: build #Standard entry point, run release
@echo "BUILD DONE"
.PHONY: build
build: $(PROGRAM_NAME)
@echo "BUILD DONE"
$(PROGRAM_NAME): $(OBJECTS)
@echo "Link executable"
$(CXX) -o $(BUILD_DIR)/$(PROGRAM_NAME) $(addprefix $(BUILD_DIR)/,$(OBJECTS))
$(OBJECTS): %.obj: %.cpp
@echo "Compile into object code: $<"
${CXX} $(CXXFLAGS) -c $< -o $(BUILD_DIR)/$@ #Compiles object code and places it in the $(BUILD_DIR)
更新1:基於一些程序員dude的評論,我用-p運行它,並得到以下有趣的結果:
# Not a target:
DEM.cpp:
# Implicit rule search has been done.
# File does not exist.
# File has not been updated.
# Not a target:
World.cpp:
# Implicit rule search has not been done.
# Modification time never checked.
# File has not been updated.
# Lot more targets below
似乎只是找不到DEM.cpp,而是找到其他所有內容。 DEM.cpp位於C:\\ Users \\ dklomp \\ Documents \\ Programming \\ C ++ Source \\ DEM \\ DEM \\ Code,但應解析為。\\ Code \\其他大多數文件位於Code的子目錄中。 但是stdafx.cpp也駐留在。\\ Code \\中,並且找到它沒有問題。
目錄名稱DEM是否類似於DEM.cpp可能是名稱沖突?
更新2:有關信息和結束。 我已經通過打印變量讀取變量來檢查VPATH,這似乎提供了正確的信息。 但是,如果我用@(info $ {VPATH))閱讀它,它似乎是空的:
@echo "VPATH print variable: "
@echo "$(VPATH)"
@echo "VPATH print info: "
$(info VPATH)
放棄:
"VPATH print variable: "
"./Code/InputOutput/ ./Code/InputOutput/ ./Code/InputOutput/
./Code/InputOutput/ ./Code/ ./Code/ ./Code/Models/ ./Code/Models/
./Code/Forces/ ./Code/Forces/ ./Code/Forces/ ./Code/Forces/ ./Code/Forces/
./Code/Forces/ ./Code/Forces/ ./Code/Forces/ ./Code/Forces/ ./Code/Tools/
./Code/Tools/ ./Code/Tools/ ./Code/Tools/ ./Code/Solvers/ ./Code/Solvers/
./Code/Solvers/ ./Code/World/ ./Code/World/ ./Code/World/ ./Code/World/
./Code/World/ ./Code/Interactions/ ./Code/Interactions/ ./Code/Interactions/
./Code/Interactions/ ./Code/Interactions/ ./Code/Interactions/
bin\Release"
"VPATH print info: "
確實有很多重復(將使用hardcoreHenry的排序建議),但是看起來不錯。 但是,由於某些原因,VPATH信息為空。
但是,通過code_fodder實現建議的解決方案並刪除所有內聯代碼注釋是可行的。 變量聲明中的內聯代碼注釋似乎無關緊要,rules部分中的注釋對於Windows而言確實有用,Linux似乎可以在任何地方很好地處理內聯代碼注釋。
像往常一樣感謝您的幫助和建議。
我在當前位置之前有空格的路徑中對此進行了測試(例如, d:\\path with spaces\\myfolder\\sub_folder1\\sub_folder2\\
)。
我認為FORFILES語法/輸出存在一些問題-至少我無法使其正常工作。 從這里第二個答案開始使用更通用的rwildcard時,它就開始很好地工作。 然后,我添加了創建/清理輸出文件夾的規則。
我也刪除了任何內聯注釋,因為我不是100%確信它們是有效的,因為它們到處都留有空格字符,並且makefile對此不太寬容... IE確保您不會在任何行上留下任何尾隨空白。
另外-這一切都假設其是gnu-make
而並非nmake
# MAKEFILE
# Some makefile settings
SHELL = /bin/sh
.SUFFIXES:
.SUFFIXES: .cpp .obj
# Variable Declaration
CXX := g++
BUILD_DIR = .\bin\Release
PROGRAM_NAME := DEM.exe
# Define a recursive wild card function that is portable.
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
#SOURCES := $(shell FORFILES /S /M *.cpp /C "CMD /C ECHO @relpath")
SOURCES := $(call rwildcard, ./, *.cpp)
$(info SOURCES: $(SOURCES))
NAMES := $(notdir $(basename $(SOURCES)))
OBJECTS := $(addsuffix .obj, $(NAMES))
SRC_DIRS := $(dir $(SOURCES))
VPATH := $(SRC_DIRS) $(BUILD_DIR)
.PHONY: all
all: create_dirs build
@echo "BUILD DONE"
# Has an order dependency on create_dirs to ensure that happens first, and so
# it works with parallel build (e.g. `make -j4`)
.PHONY: build
build: $(PROGRAM_NAME) | create_dirs
@echo "BUILD DONE"
$(PROGRAM_NAME): $(OBJECTS)
@echo "Link executable"
$(CXX) -o $(BUILD_DIR)/$(PROGRAM_NAME) $(addprefix $(BUILD_DIR)/,$(OBJECTS))
$(OBJECTS): %.obj: %.cpp
@echo "Compile into object code: $<"
${CXX} $(CXXFLAGS) -c $< -o $(BUILD_DIR)/$@
.PHONY: create_dirs
create_dirs:
@echo "creating dirs"
mkdir -p $(BUILD_DIR)
.PHONY: clean
clean:
@echo "cleaning"
rm -rf $(BUILD_DIR)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.