【问题标题】:Problem with makefile after rename variable重命名变量后makefile出现问题
【发布时间】:2019-06-14 16:28:20
【问题描述】:

在将变量名称更改为 makefile 后,其行为发生了巨大变化。从不成功的编译到成功的编译。

我尝试了所有方法 - 不同的名称,添加了各种附加条件,但都没有成功。

品牌版本:

$make --version
GNU Make 3.82
Built for x86_64-redhat-linux-gnu
Copyright (C) 2010  Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

这是一个源代码文件

int main(int argc, char *argv[])
{
        return 0;
}

原始(期望的)行为生成文件:

SHELL = /bin/sh
.SUFFIXES:
.SUFFIXES: .c .o

CC := gcc
LD := gcc

CFLAGS := -g

STRICT_CFLAGS := -Wall -Wextra -Wpedantic -Werror
INCLUDE_CFLAGS := 
ALL_CFLAGS := $(INCLUDE_CFLAGS) $(STRICT_CFLAGS) $(CFLAGS)


STRICT_LDFLAGS := -Wall -Wextra -Wpedantic -Werror
INCLUDE_LDFLAGS := 
LDFLAGS := $(STRICT_LDFLAGS) $(INCLUDE_LDFLAGS) $(CFLAGS)

SOURCES := $(wildcard *.c)
BINARIES := $(SOURCES:%.c=%)

.PHONY: all
all: $(BINARIES)

%: %.o
    @echo "Checking..."
    $(LD) $(LDFLAGS) -o $@

.c.o:
    @echo "Creating object..."
    $(CC) $(ALL_CFLAGS) -c $< -o $@

.PHONY: clean
clean:
    @echo "Cleaning up..."
    -rm -rvf *.o $(BINARIES)

编译输出:

$make
gcc -g  -Wall -Wextra -Wpedantic -Werror  -g  test.c   -o test
test.c: In function ‘main’:
test.c:1:14: error: unused parameter ‘argc’ [-Werror=unused-parameter]
} return 0;nt argc, char *argv[])
              ^
test.c:1:26: error: unused parameter ‘argv’ [-Werror=unused-parameter]
} return 0;nt argc, char *argv[])
                          ^
cc1: all warnings being treated as errors
make: *** [test] Error 1

重命名变量后的生成文件 (LDFLAGS -> T_LDFLAGS) - 错误行为:

SHELL = /bin/sh
.SUFFIXES:
.SUFFIXES: .c .o

CC := gcc
LD := gcc

CFLAGS := -g

STRICT_CFLAGS := -Wall -Wextra -Wpedantic -Werror
INCLUDE_CFLAGS := 
ALL_CFLAGS := $(INCLUDE_CFLAGS) $(STRICT_CFLAGS) $(CFLAGS)


STRICT_LDFLAGS := -Wall -Wextra -Wpedantic -Werror
INCLUDE_LDFLAGS := 
T_LDFLAGS := $(STRICT_LDFLAGS) $(INCLUDE_LDFLAGS) $(CFLAGS)

SOURCES := $(wildcard *.c)
BINARIES := $(SOURCES:%.c=%)

.PHONY: all
all: $(BINARIES)

%: %.o
    @echo "Checking..."
    $(LD) $(T_LDFLAGS) -o $@

.c.o:
    @echo "Creating object..."
    $(CC) $(ALL_CFLAGS) -c $< -o $@

.PHONY: clean
clean:
    @echo "Cleaning up..."
    -rm -rvf *.o $(BINARIES)

编译输出:

$make
gcc -g    test.c   -o test

请有人向我解释一下,为什么在名称更改后,我们会丢失严格代码的标志。

感谢您的宝贵时间!

【问题讨论】:

    标签: variables makefile rename behavior


    【解决方案1】:

    你的两个制造目标都没有被击中。如果查看输出,您会注意到Checking... 没有打印出来,Creating object... 也没有打印出来。因此,您的程序正在使用默认目标构建。此默认目标自动将$(CFLAGS)$(LDFLAGS) 添加到构建行。这就是为什么当你重命名 LDFLAGS 时一切都停止了。

    此外,您的 makefile 当前正在尝试为每个单独的 .c 文件创建一个可执行文件。

    您需要按如下方式更改目标:

    SOURCES := $(wildcard *.c)
    OBJECTS := $(SOURCES:%.c=%.o)
    BINARY := myprog
    
    .PHONY: all
    all: $(BINARY)
    
    $(BINARY): $(OBJECTS)
        @echo "Checking..."
        $(LD) $(T_LDFLAGS) $(OBJECTS) -o $@
    
    %.o: %.c
        @echo "Creating object..."
        $(CC) $(ALL_CFLAGS) -c $< -o $@
    

    OBJECTS 变量将包含与每个 .c 文件对应的 .o 文件列表。这将是二进制文件的依赖列表和要链接的对象列表。目标文件的目标是为每个 .c 文件创建一个 .o 文件。

    【讨论】:

    • 哇,10x dbush...非常感谢您的帮助,显然我还有很多东西要学。但正是这些问题对我们有所帮助——经过 5-6 小时的研究和实验未能解决问题,但学到了更多!
    • $(BINARIES) : $(BINARIES).o 行是错误的,除非您的目录中只有一个源文件。一旦你有多个,这将严重破坏。
    • @MadScientist 你是对的!您知道问题是什么以及如何解决吗?提前 10 倍!
    • 问题是:如果BINARIES 包含foo bar 那么上面的行扩展到foo bar : foo bar.o 这显然是不对的。您不能只在变量末尾添加 .o 并以某种方式期望它应用于该变量中的每个单词......它不是。它只是附加到变量值的末尾。即使它确实被附加了(假设你将它重写为$(BINARIES): $(addsuffix .o,$(BINARIES)) 它仍然是不正确的:它会使每个二进制文件都依赖于所有对象文件。
    • 在我们为您提供帮助之前,您需要澄清:真的是不是您目录中的每个 .c 文件都编译成一个单独的程序?这就是你的声明BINARIES := $(SOURCES:%.c=%) 所说的。这并不常见:通常一个程序是由多个源文件构建的。这个问题的答案对于什么是合理的解决方案有很大的影响。
    猜你喜欢
    • 1970-01-01
    • 2011-06-14
    • 2015-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-06
    相关资源
    最近更新 更多