如何使用 make 构建 CS50 程序

How to build CS50 programs with make

我正在尝试在 linux 上学习 cs50,我下载了在 github 上找到的所有内容,但现在我无法使用 make 编译我的第一个程序,但我可以改用 clang clang hello.c -lcs50 -o hello 效果很好,但是当我尝试使用 make hello 进行编译时,我得到

:~/cs50/pset1# make hello
cc     hello.c   -o hello
/usr/bin/ld: /tmp/cczILfhu.o: in function 'main':
hello.c:(.text+0x1a): undefined reference to 'get_string'
collect2: error: ld returned 1 exit status
make: *** [<builtin>: hello] Error 1

我什至把我下载的libcs​​50文件夹移到/usr/include/ 但我仍然得到相同的结果。 在我用 clang 编译之后,然后执行 make hello 它说 make: 'hello' 是最新的。 我知道这听起来很垃圾,但我仍然是新手,正在寻求帮助。 提前致谢。

对于 cs50 库中的链接(您应该根据那里的说明从 https://github.com/cs50/libcs50 安装),您的链接命令应该指定 -lcs50 参数。

make 通常需要一个 Makefile 来控制构建。如果它不存在,它可以使用一些隐式规则来猜测构建过程,例如 hello.o 可以从 hello.c 构建并且 hello 可以从 hello.o 链接等等,但它肯定猜不到 libcs50 应该被链接进来。

幸运的是,隐式链接规则正确地包含了变量 LDLIBS 的内容,因此您可以通过在同一目录中编写一个简单的 Makefile 来解决这个问题,只包含 [=42] =]

LDLIBS += -lcs50

即“将字符串 -lcs50 附加到 LDLIBS 的当前值”。

之后make hello会使用隐式规则LDLIBS的新值来执行

cc     hello.c  -lcs50 -o hello

另请注意,cc 命令通常是 GCC,而不是 Clang,这在 CS50 中并不重要。可以用Makefile中的CC变量配置:

CC := clang

最后,在 compilation 标志中启用警告和迂腐确实有意义,例如:

CFLAGS += -Wall -Wextra -Werror -pedantic -std=c11

有了所有这 3 个,make hello 将实际执行

clang -Wall -Wextra -Werror -pedantic -std=c11    hello.c  -lcs50 -o hello

这意味着我们确实节省了大量的输入并获得了更多有用的诊断!


当然,对于更复杂的构建过程,您需要使用依赖规则编写更复杂的 Makefile - 假设您的 helloworld 程序由 hello.cworld.c 链接在一起,你可以通过隐式规则得到,只需声明 helloworld 取决于 hello.oworld.o 并且应该从这些链接在一起:

helloworld: hello.o world.o
        $(CC) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS)

# the command *must* be indented by a *single* tab character, not spaces!
# unfortunately SO editor does not make it easy to write tabs.