Makefile 当我运行'make debug'时,用额外的一个附加构建标志`

Makefile 当我运行'make debug'时,用额外的一个附加构建标志`,makefile,gnu-make,Makefile,Gnu Make,在我的例子中,我想进行一些调试构建,以便能够在构建系统中运行gdb: HOST ?=127.0.0.1 PORT ?=7070 CCFLAGS="-std=c++11" CPP=g++ ${CCFLAGS} CFLAGS_DBG=" -g -DDEBUG" TEST_BUILD_PATH="./build/tests" BUILD_PATH=./build/release TESTS_SRC_PATH="./tests" DEBUGER=gdb # NORMAL TARGETS buil

在我的例子中,我想进行一些调试构建,以便能够在构建系统中运行gdb:

HOST ?=127.0.0.1
PORT ?=7070

CCFLAGS="-std=c++11"
CPP=g++ ${CCFLAGS}
CFLAGS_DBG=" -g -DDEBUG"
TEST_BUILD_PATH="./build/tests"
BUILD_PATH=./build/release
TESTS_SRC_PATH="./tests"
DEBUGER=gdb


# NORMAL TARGETS

build_commandParser: ./src/tools/command_parser.cpp ./src/tools/command_parser.h
    ${CPP} -Wall -g -c ./src/tools/command_parser.cpp -o ${BUILD_PATH}/command_parser.o

build_network: ./src/socket/network.cpp ./src/socket/network.h
    ${CPP} -Wall -g -c ./src/socket/network.cpp -o ${BUILD_PATH}/network.o

build_simpleCommand: ./src/socket/simple_command.cpp ./src/socket/simple_command.h
    ${CPP} -Wall -g -c ./src/socket/simple_command.cpp -o ${BUILD_PATH}/simple_command.o

build: build_simpleCommand build_commandParser build_network ./src/main.cpp
    ${CPP} -pthread -Wall -o ${BUILD_PATH}/server ${BUILD_PATH}/command_parser.o ${BUILD_PATH}/network.o ${BUILD_PATH}/simple_command.o ./src/main.cpp

run: build
    ${BUILD_PATH}/server -h ${HOST} -p ${PORT}

debug: build
    ${DEBUGER} --args ${BUILD_PATH}/server -h ${HOST} -p ${PORT}

clean:
    find ./build ! -name '.gitkeep' -type f -exec rm -f {} + && find ./tests ! -name *.h -type f -exec rm -f {} +
如您所见,我尝试统一
CFLAGS\u DBG
变量以传递调试标志。但正如您所看到的,is未能做到这一点:

g++ -pthread -Wall -std=c++11  -c ./src/socket/simple_command.cpp -o ./build/release/simple_command.o
g++ -pthread -Wall -std=c++11  -c ./src/tools/command_parser.cpp -o ./build/release/command_parser.o
g++ -pthread -Wall -std=c++11  -c ./src/socket/network.cpp -o ./build/release/network.o
g++ -pthread -Wall -std=c++11  -o ./build/release/server ./build/release/command_parser.o ./build/release/network.o ./build/release/simple_command.o ./src/main.cpp

我还尝试此设置:

HOST ?=127.0.0.1
PORT ?=7070

CCFLAGS=-pthread -Wall -std=c++11
CCFLAGS_DBG=
CPP=g++
TESTGEN=cxxtestgen
TEST_BUILD_PATH="./build/tests"
BUILD_PATH=./build/release
TESTS_SRC_PATH="./tests"
DEBUGER=gdb

# NORMAL TARGETS

build_commandParser: ./src/tools/command_parser.cpp ./src/tools/command_parser.h
    ${CPP} ${CCFLAGS} ${CCFLAGS_DBG} -c ./src/tools/command_parser.cpp -o ${BUILD_PATH}/command_parser.o

build_network: ./src/socket/network.cpp ./src/socket/network.h
    ${CPP} ${CCFLAGS} ${CCFLAGS_DBG} -c ./src/socket/network.cpp -o ${BUILD_PATH}/network.o

build_simpleCommand: ./src/socket/simple_command.cpp ./src/socket/simple_command.h
    ${CPP} ${CCFLAGS} ${CCFLAGS_DBG} -c ./src/socket/simple_command.cpp -o ${BUILD_PATH}/simple_command.o

build: build_simpleCommand build_commandParser build_network ./src/main.cpp
    ${CPP} ${CCFLAGS} ${CCFLAGS_DBG} -o ${BUILD_PATH}/server ${BUILD_PATH}/command_parser.o ${BUILD_PATH}/network.o ${BUILD_PATH}/simple_command.o ./src/main.cpp

run: build
    ${BUILD_PATH}/server -h ${HOST} -p ${PORT}

.PHONY: debug-flags
debug-flags: CCFLAGS+=-g -DDEBUG

debug: debug-flags build
    ${DEBUGER} --args ${BUILD_PATH}/server -h ${HOST} -p ${PORT}

clean:
    find ./build ! -name '.gitkeep' -type f -exec rm -f {} + && find ./tests ! -name *.h -type f -exec rm -f {} +

我仍然得到上面的输出。因此,当我使用
makedebug
构建时,我希望能够指定额外的标志,并为链接器设置新的标志。你有什么办法吗?

正如问题评论中所说, 这里的建造过程有点不卫生。 我建议你换一下

也就是说,做你想做的事是可能的,也很简单。 因此,通过阐述, 草图:

$ cat Makefile
flags := normal
debug: flags := overridden

build:
    : $@ flags: ${flags}

debug: build
    : $@ done
这里我们有一个特定于目标的变量
flags
标志
通常为
正常
。 然而, 当构建
调试
或其任何依赖项时,它将被
覆盖

build
以一种不足为奇的方式使用
$flags

$ make build
: build flags: normal
令人惊讶的是,通过
debug
生成
build
时使用的值是
debug
的目标特定值:

$ make debug
: build flags: overridden
: debug done
忠告 不要对原始makefile执行此操作。 如果你这样做,你的生活将变得悲惨。 考虑:

  • make build
  • 编辑
  • 进行调试
  • 你最终会得到某种弗兰肯建筑——一个用碎片建造的怪物。 如果你运气不好,它甚至可能链接

    你成功的唯一保证就是每次都做一个干净的构建。
    一个可怕的MaxFrm文件的典型标志。

    这里有两个问题,但是请考虑一下:你如何处理一个事实,即你可以构建两个不同版本的对象文件,比如<代码>命令行分析器?o>代码>?假设存在一个同名文件,然后尝试进行调试;如何知道该文件是否使用正确的标志生成,以及是否必须重新生成?一种解决方案是为不同版本保留两个不同的生成目录(例如
    build/release
    build/debug
    ),另一种方法是为它们指定不同的名称(例如
    command\u parser.o
    command\u parser\u debug.o
    )。任何偏好?目标应为文件的一般建议;不总是这样,但这是总的方向。或者,更一般地说,不是动词而是名词。这样,make就可以为您构建一个最佳的DAG。令人惊讶的是,我不能给谷歌一个明确的指南。所以我应该考虑使用一个不同的Mag文件进行调试,对吗?但如果我这么做就不会是一个维护地狱?但是我可以使用“调试前清除”作为标记。@Dimitrisdesylas不,您应该将所有生成产品都排除在源代码树之外。一个makefile就可以了(建议使用)。这样,您就可以(比如)有一个
    \u build/
    文件夹用于
    生成
    的输出,还有一个
    \u debug/
    文件夹用于
    生成调试
    的输出。很好,很有逻辑。你甚至不需要一个
    makeclean
    ,因为
    rm-rf\u debug/
    更简单,更干净。(前缀
    表示文件夹是临时的,如果再次需要,可以重新生成。)