gpt4 book ai didi

c++ - Makefile 在 Linux 下工作但在 Windows 下不工作,无法在子目录中找到文件

转载 作者:可可西里 更新时间:2023-11-01 10:41:03 32 4
gpt4 key购买 nike

我有一个在 linux 下工作的 makefile (gnu make),但是当把它移植到 windows 时它不工作。 makefile 的目标是制作位于不同子目录中的所有 *.cpp 文件,并将它们编译成单个 BUILD_DIR 中的 *.obj 文件。

在 linux 和 windows 之间我只调整了 SOURCES 变量,显示了 linux 行但注释了。当我检查所有名称和目录时,它们显示相同的(它们的透视表示法中的相对路径)和我所期望的。

我在 Windows 上收到的“错误消息”是:make: *** No rule to make target 'DEM.cpp', needed by 'DEM.obj'。停止。

在 Debug模式下它说:文件“DEM.cpp”不存在。 (它显然是这样做的)

在 Linux 上,它通过 VPATH 找到文件,在 Debug模式下它说:不需要重新制作目标“DEM.cpp”;使用 VPATH 名称“./Code/DEM.cpp”。

linux 和 windows 的子目录结构相同,makefile 从相同的位置运行。

问题:这里出了什么问题,我感觉这与 VPATH 在 Windows 上的处理方式不同有关,但我不确定。

我的 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: 基于 some programmer 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\大多数其他文件位于代码的子目录中。但 stdafx.cpp 也位于 .\Code\中,找到它没有问题。

会不会是跟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 实现建议的解决方案并删除所有内联代码注释是可行的。变量声明的内联代码注释似乎无关紧要,规则部分中的注释适用于 windows,linux 似乎在任何地方都可以很好地处理内联代码注释。

一如既往地感谢您的帮助和建议。

最佳答案

我在当前位置之前有空格的路径中进行了测试(例如,d:\path with spaces\myfolder\sub_folder1\sub_folder2\)。

我认为 FORFILES 语法/输出存在一些问题 - 至少我无法让它工作。一旦我使用了来自 second answer from here 的更通用的 rwildcard它开始运作良好。然后我添加了创建/清理输出文件夹的规则。

我还删除了任何内联注释,因为我不能 100% 确定它们是否有效,因为它们到处都留有空格字符,而 makefile 对此不是很宽容...... I.E.确保您没有在任何行中留下任何尾随空格。

另外 - 这一切都假定它的 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)

关于c++ - Makefile 在 Linux 下工作但在 Windows 下不工作,无法在子目录中找到文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57474727/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com