使用GNU Make同时构建调试和发布目标(扩展)

时间:2016-01-03 05:22:52

标签: c gcc makefile gnu-make

我想跟进this question and its answers ...现在我可以构建两个不同的可执行文件,我想根据变量在不同的目录中构建可执行文件。

我想从以下的地方出发:

EXEDIR     = bin/release/
EXE        = $(EXEDIR)AmiModRadio
SOURCES    = $(wildcard *.c)
OBJECTSDIR = o/release/
OBJECTS    = $(addprefix $(OBJECTSDIR), $(SOURCES:.c=.o))

CC = vbcc:bin/vc
LD = vbcc:bin/vc

release : $(EXE) 
$(OBJECTS) : $(OBJECTSDIR)%.o : %.c
    $(CC) $(shell vbccprefs) -c $< -o $@
$(EXE) : $(OBJECTS)
    $(LD) $(shell vbccprefs) -o $(EXE) $(OBJECTS)

类似于:

EXE        = $(EXEDIR)AmiModRadio
SOURCES    = $(wildcard *.c)
OBJECTS    = $(addprefix $(OBJECTSDIR), $(SOURCES:.c=.o))

CC = vbcc:bin/vc
LD = vbcc:bin/vc

release : EXEDIR = bin/release/
release : OBJECTSDIR = o/release/
release : $(EXE) 

release : EXEDIR = bin/debug/
release : OBJECTSDIR = o/debug/
release : $(EXE) 

$(OBJECTS) : $(OBJECTSDIR)%.o : %.c
    $(CC) $(shell vbccprefs) -c $< -o $@
$(EXE) : $(OBJECTS)
    $(LD) $(shell vbccprefs) -o $(EXE) $(OBJECTS)

上面的最后一个makefile不起作用,因为据我所知,在规则EXEDIROBJECTSDIR中设置变量releasedebug为时已晚。

那么,我在这里错过了一些简单的东西吗?有没有办法让两个规则releasedebug使用相同的规则,但是在两个不同的目录集中生成文件,包括作为主要目标的可执行文件?

2 个答案:

答案 0 :(得分:2)

您可以调用以下Makefile:

make release
make debug

- 或 -

make BUILD=release
make BUILD=debug

<强>生成文件

ifneq ($(BUILD),release)
    BUILD = debug
endif

EXEDIR      = bin/$(BUILD)/
OBJDIR      = o/$(BUILD)/

EXE         = $(EXEDIR)AmiModRadio
SOURCES     = $(wildcard *.c)
OBJECTS     = $(addprefix $(OBJDIR), $(SOURCES:.c=.o))

CC = vbcc:bin/vc
LD = vbcc:bin/vc

CFLAGS  = $(shell vbccprefs)
LDFLAGS = $(shell vbccprefs)

all : $(EXE)

.PHONY : release debug    
release debug :
    $(MAKE) BUILD=$@

$(EXE) : $(OBJECTS)
    $(LD) $(LDFLAGS) -o $@ $^

$(OBJDIR)%.o : %.c
    $(CC) $(CFLAGS) -o $@ -c $<

答案 1 :(得分:1)

我会使用条件来确定目标是什么,并相应地设置变量。

"""
    Calculate required monthly repayment for a given:
        - loan amount, and
        - annual interest rate, and
        - period of repayments in months

    You can nominate the accuracy required by adjusting the value of
        ACCURACY_AS_PARTS_OF_CENT. For example:
        - .01 = accurate to a dollar
        - .1  = accurate to 10 cents
        - 1   = accurate to cent
        - 100 = accurate to 100th of a cent
"""

# Set constants.
LOAN_AMOUNT = 7692
ANNUAL_INTEREST_PERCENT = 18
REPAY_MONTHS = 12
ACCURACY_AS_PARTS_OF_CENT = 1

loan_amount = int(LOAN_AMOUNT * 100 * ACCURACY_AS_PARTS_OF_CENT)
monthly_interest = float(ANNUAL_INTEREST_PERCENT / 100 / 12)
repay_guess_min = int((LOAN_AMOUNT / REPAY_MONTHS) - 1)
result_found = False
repayment_required = 0

for repay_guess in range(repay_guess_min, loan_amount):
    if result_found:
        break
    loan_balance = loan_amount
    for _ in range(REPAY_MONTHS):
        interest_to_add = loan_balance * monthly_interest
        loan_balance = loan_balance + interest_to_add - repay_guess
        if loan_balance <= 0:
            repayment_required = repay_guess / 100 / ACCURACY_AS_PARTS_OF_CENT
            result_found = True
            break

print('Required monthly repayment = $' + str(repayment_required))

我在您的代码中看到的一个大问题是您在发布和调试路径上指定了发布目标。所以GNU Make使用它遇到的最后一个赋值。但是,使用我在这里的东西应该可以正常工作,因为我做了类似于我的make文件。

执行此操作时,您无法在命令行上指定发布和调试,因为它们是互斥的。 strip函数从参数中去掉前导和尾随空格,该参数是过滤函数的输出。 filter函数接受字符串调试并在预定义变量MAKECMDGOALS中查找它。 MAKECMDGOALS是命令行中指定的所有目标(目标)的列表。

希望这有帮助。