Makefile如何为源代码和二进制文件使用单独的目录?

Makefile如何为源代码和二进制文件使用单独的目录?,makefile,Makefile,我希望能够将我的bin和代码文件拆分到单独的目录中,因为在当前状态下管理起来越来越困难 我理想的情况是 project_dir |-Makefile |-run_tests.sh | |__source | |-program1.cpp | |-program2.cpp | |__bin |-program1 |-program2 但是,如果不手动编写每个程序的规则,我就无法在当前系统中使用它(请记住,每个程序都是一个单独的程序,而不是一系列链接在一起的对象) #当前制造系统

我希望能够将我的bin和代码文件拆分到单独的目录中,因为在当前状态下管理起来越来越困难

我理想的情况是

project_dir
|-Makefile
|-run_tests.sh
|
|__source
|  |-program1.cpp
|  |-program2.cpp
|
|__bin
   |-program1
   |-program2
但是,如果不手动编写每个程序的规则,我就无法在当前系统中使用它(请记住,每个程序都是一个单独的程序,而不是一系列链接在一起的对象)

#当前制造系统
仓位=/仓位/
来源=/来源/
列表=程序1程序2。。。
全部:$(列表)
%:$(来源)%.cpp
$(CC)$(INC)$<$(CFLAGS)-o$(BIN)$@$(LIBS)
这是可行的,只是我看不到当前路径中的目标,所以它认为即使源文件没有更改,它也会重建二进制文件


我现在唯一的想法是编写一个程序来生成一个makefile,但我不想这样做。

你就快到了

#Current make system
BIN=./bin/
SOURCE=./source/

LIST=$(BIN)/program1 $(BIN)/program2...

all: $(LIST)

$(BIN)/%:  $(SOURCE)%.cpp
    $(CC) $(INC) $< $(CFLAGS) -o $@ $(LIBS)

简单的解决方案:使用
automake


如果要手动执行此操作,则需要使用
vpath
指令或
vpath
环境变量。GNU make手册对它们进行了详细介绍。将Makefile直接放入
bin
目录,将
VPATH
设置为源目录,隐式规则将再次工作。

这里是完整的Makefile现成版本

使用以下目录准备文件夹

对于.o文件:
/build/
对于.cpp文件:
/src/
对于二进制文件:
/bin/

然后在
/

CC          = g++
LD          = g++ 
CFLAG       = -Wall
PROG_NAME   = prog

SRC_DIR     = ./src
BUILD_DIR   = ./build
BIN_DIR     = ./bin
SRC_LIST = $(wildcard $(SRC_DIR)/*.cpp)
OBJ_LIST = $(BUILD_DIR)/$(notdir $(SRC_LIST:.cpp=.o))

.PHONY: all clean $(PROG_NAME) compile

all: $(PROG_NAME)

compile: 
    $(CC) -c $(CFLAG) $(SRC_LIST) -o $(OBJ_LIST)

$(PROG_NAME): compile
    $(LD) $(OBJ_LIST) -o $(BIN_DIR)/$@

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

您的最终程序将在
/bin/
中命名为prog,每次编译代码时,二进制文件将在
/build/
处分开,这样源代码目录将非常整洁干净。

如果可以使用精心制作的make文件来完成,则不支持automake;不过,我不会称自动工具为“easy”。这可能是个愚蠢的问题,但有没有办法在命令行上使用“%”变量(即无名称目录)。所以“gcc blah blah-D%”(这样程序就知道它自己的名字)是的,你可以使用
$*
来获取stem。非常好,我想我的make文件就要完成了,谢谢你的帮助。我刚刚看到你加了:“addprefix”,这更好了,再次感谢:)传统的方法是调用源目录
src
,在那里构建二进制文件,并有一个单独的步骤
install
,其中二进制文件被复制到
bin
目录-甚至有一个特殊的实用工具
install
来完成这一工作。你的解决方案可以工作,但会重建一切有点悲伤的东西。这不是“有点悲伤”,而是违背了使用make的全部目的-1.
PROG=program1 program2
LIST=$(addprefix $(BIN)/, $(PROG))
CC          = g++
LD          = g++ 
CFLAG       = -Wall
PROG_NAME   = prog

SRC_DIR     = ./src
BUILD_DIR   = ./build
BIN_DIR     = ./bin
SRC_LIST = $(wildcard $(SRC_DIR)/*.cpp)
OBJ_LIST = $(BUILD_DIR)/$(notdir $(SRC_LIST:.cpp=.o))

.PHONY: all clean $(PROG_NAME) compile

all: $(PROG_NAME)

compile: 
    $(CC) -c $(CFLAG) $(SRC_LIST) -o $(OBJ_LIST)

$(PROG_NAME): compile
    $(LD) $(OBJ_LIST) -o $(BIN_DIR)/$@

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