You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Makefile将C++目标文件输出到App目录时构建失败

C++ Makefile无法将目标文件生成到App目录,构建失败

问题概述

尝试将C++程序的目标文件与可执行文件输出至App独立目录,但构建失败,目标文件未生成到指定目录。

错误信息

make: *** No rule to make the target 'App/src/Player/Player.o', needed by 'build'. Stop.

目录结构

drwxrwxr-x    - akashdiphazra  3 Jul 23:17 ├──  App (Dir of object and exe files)
.rwxrwxr-x  35k akashdiphazra  3 Jul 23:17 │  
.rwxrwxr-x  619 akashdiphazra  3 Jul 23:17 ├── Makefile
drwxrwxr-x    - akashdiphazra  3 Jul 23:17 └── src (Dir)
.rwxrwxr-x  205 akashdiphazra  3 Jul 14:29    ├── main.cpp
                                              |
drwxrwxr-x    - akashdiphazra  3 Jul 23:17    └── Player (Dir)
.rwxrwxr-x  135 akashdiphazra  3 Jul 14:24       ├── Player.cpp
.rwxrwxr-x  284 akashdiphazra  3 Jul 14:24       ├── Player.h

原Makefile代码

CC = g++
CXXFLAGS = -Wall -Wextra -Werror -std=c++20 -pedantic -ggdb
EXECUTABLE_NAME = akash
MEMORY_SAFE_FLAGS= -fsanitize=address -fno-omit-frame-pointer
BUILD_DIR = App

CXX_SOURCES = $(wildcard  src/*.cpp src/**/*.cpp)  
CXX_OBJECTS = $(patsubst %.cpp, $(BUILD_DIR)/%.o, $(CXX_SOURCES)) 

all: build execute 

build: $(CXX_OBJECTS)
    $(CC) $(CXXFLAGS) $(CXX_OBJECTS) $(LDFLAGS) -o $(BUILD_DIR)/$(EXECUTABLE_NAME)

execute:
    ./$(BUILD_DIR)/$(EXECUTABLE_NAME)

clean:
    rm -f $(BUILD_DIR)/*.o

$(BUILD_DIR)/%.o : %.cpp
    $(CC) $(CFLAGS) -c $^ -o $@

问题分析

  1. 嵌套目录未自动创建:目标文件路径如App/src/Player/Player.o包含多层子目录,make不会自动创建这些目录,导致无法生成文件。
  2. 编译参数错误:使用了C语言的$(CFLAGS)而非C++的$(CXXFLAGS),编译选项缺失可能引发问题。
  3. clean规则不完整:仅删除App/*.o,但目标文件实际在App/src及子目录下,无法彻底清理。
  4. 内存安全标志未在链接阶段使用:定义了MEMORY_SAFE_FLAGS但未加入链接命令,若启用地址 sanitizer会失效。

修正后的Makefile

CC = g++
CXXFLAGS = -Wall -Wextra -Werror -std=c++20 -pedantic -ggdb
EXECUTABLE_NAME = akash
MEMORY_SAFE_FLAGS= -fsanitize=address -fno-omit-frame-pointer
BUILD_DIR = App

# 递归获取所有cpp文件(确保make支持**通配符,若不支持可替换为find src -name "*.cpp")
CXX_SOURCES = $(wildcard src/*.cpp src/**/*.cpp)  
# 转换源文件路径为App目录下的目标文件路径
CXX_OBJECTS = $(patsubst %.cpp, $(BUILD_DIR)/%.o, $(CXX_SOURCES)) 

all: build execute 

build: $(CXX_OBJECTS)
	$(CC) $(CXXFLAGS) $(MEMORY_SAFE_FLAGS) $(CXX_OBJECTS) $(LDFLAGS) -o $(BUILD_DIR)/$(EXECUTABLE_NAME)

execute:
	./$(BUILD_DIR)/$(EXECUTABLE_NAME)

clean:
	rm -rf $(BUILD_DIR)/src
	rm -f $(BUILD_DIR)/$(EXECUTABLE_NAME)

# 编译规则:先创建目标文件所在目录,再编译
$(BUILD_DIR)/%.o : %.cpp
	@mkdir -p $(dir $@)
	$(CC) $(CXXFLAGS) $(MEMORY_SAFE_FLAGS) -c $< -o $@

关键修改说明

  • 自动创建嵌套目录:添加@mkdir -p $(dir $@),在编译每个目标文件前自动生成其所在的多层目录,避免因目录不存在导致的构建失败。
  • 修正编译参数:替换$(CFLAGS)为$(CXXFLAGS),确保使用C++编译选项。
  • 完善clean规则:递归删除App/src目录清理所有目标文件,同时删除可执行文件。
  • 链接阶段加入内存安全标志:将MEMORY_SAFE_FLAGS添加到链接命令中,确保地址 sanitizer正常工作。
  • 优化编译依赖引用:用$<(第一个依赖文件)代替$^(所有依赖文件),单文件编译更准确。

内容的提问来源于stack exchange,提问作者Akashdip Hazra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 03:17:40