【发布时间】:2021-11-24 16:50:53
【问题描述】:
我在使用当前的 make 设置将所有生成的 obj 文件链接到可执行文件时遇到问题。我的目录结构如下(仅供参考):
- 根
- bin
- 包括
- project1 ... 项目N
- 生成文件
- 根/bin
- 项目1 ...项目N
- bin
- 对象
- 项目1 ...项目N
- 项目 1(例如)
- 包括
- 源代码
- 生成文件
如您所见,我将多个子项目存储在同一目录下,并使用对make 的递归调用来构建每个项目。首先,它从特定项目中收集所有源文件和头文件,然后编译它们并将生成的 obj 文件存储在 root/bin/project/obj 中。从这里,我想链接所有的 obj 文件并生成一个可执行文件,该文件将存储在root/bin/project/bin 目录下。
问题是,通过使用当前的 Makefile 配置,我的链接器(MSVC link.exe)只能看到 obj 目录中的第一个 obj 文件。下面提供的 Makefile 以查看编译和链接命令:
# expands to root/bin/projname/bin
TARGET_DIR := $(BINARY_DIR)/$(notdir $(patsubst %/,%,$(CURDIR)))/bin
#expands to root/bin/projname/obj
OBJ_DIR := $(BINARY_DIR)/$(notdir $(patsubst %/,%,$(CURDIR)))/obj
# expands to a list of all the obj files created from the source files (a.obj, b.obj..)
OBJECTS := \
$(notdir $(patsubst %.cpp,%.obj,$(patsubst %.c,%.obj,$(SOURCES))))
SOURCES := $(wildcard src/*.c) $(wildcard src/*.cpp)
# default target
all: dirs $(TARGET).exe
# Link
$(TARGET).exe: $(OBJ_DIR)/$(OBJECTS)
$(LNK) $(LIB_PATH) $(LIBS) /OUT:$(TARGET_DIR)/$@ $(OBJ_DIR)/$(OBJECTS)
# Compile
$(OBJ_DIR)/$(OBJECTS): $(SOURCES)
$(CC) /c $(CFLAGS) $(INCLUDES) /Fo$(OBJ_DIR)/ /EHsc $(SOURCES)
.PHONY: build
dirs:
$(MKDIR) $(TARGET_DIR)
$(MKDIR) $(OBJ_DIR)
$(MKDIR) $(TEST_DIR)
我在链接过程中遇到的错误如下:
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\\..\..\VC\vcvarsall.bat" x86_amd64 > NUL && link /NOLOGO /MACHINE:X64 /LIBPATH:"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib\x64" /DEFAULTLIB:shell32.lib /OUT:../bin/project1/bin/project1.exe ../bin/project1/obj/main.obj sort.obj
如您所见,它只链接到 objdir 中的第一个 obj 文件,而尝试链接到 Makefile 目录中的第二个 obj 文件,这当然会导致错误:`LINK : fatal error LNK1181: cannot open输入文件'sort.obj'
更新:已接受答案中提出的解决方案有效。将在下面留下最终版本。
# expands to root/bin/projname/bin
TARGET_DIR := $(BINARY_DIR)/$(notdir $(patsubst %/,%,$(CURDIR)))/bin
#expands to root/bin/projname/obj
OBJ_DIR := $(BINARY_DIR)/$(notdir $(patsubst %/,%,$(CURDIR)))/obj
# expands to a list of all the obj files created from the source files (a.obj, b.obj..)
OBJECTS := \
$(notdir $(patsubst %.cpp,%.obj,$(patsubst %.c,%.obj,$(SOURCES))))
SOURCES := $(wildcard src/*.c) $(wildcard src/*.cpp)
# default target
all: dirs $(TARGET).exe
# Link
$(TARGET).exe: $(addprefix $(OBJ_DIR)/,$(OBJECTS)))
$(LNK) $(LIB_PATH) $(LIBS) /OUT:$(TARGET_DIR)/$@ $^
# Compile
$(OBJ_DIR)/$(OBJECTS): $(SOURCES)
$(CC) /c $(CFLAGS) $(INCLUDES) /Fo$(OBJ_DIR)/ /EHscT $(SOURCES)
.PHONY: build
dirs:
$(MKDIR) $(TARGET_DIR)
$(MKDIR) $(OBJ_DIR)
$(MKDIR) $(TEST_DIR)
【问题讨论】: