Как собрать программы CS50 с помощью make - PullRequest
0 голосов
/ 11 марта 2019

Я пытаюсь изучать CS50 на Linux, я загрузил все, что я нашел на 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

Я даже переместил папку libcs50, которую я скачал, в / usr / include / но я все равно получаю те же результаты. после того, как я скомпилирую с Clang, а затем извините make hello он говорит make: 'hello' обновлен Я знаю, это звучит как дамп, но я все еще новичок и ищу помощи. заранее спасибо.

1 Ответ

2 голосов
/ 11 марта 2019

Для связывания в библиотеке cs50 (которую вы должны были установить с https://github.com/cs50/libcs50 в соответствии с инструкциями там), ваша команда связывания должна указать аргумент -lcs50.

make обычно требуется Makefile для управления сборкой. В его отсутствие он может использовать некоторые неявные правила, чтобы угадать процесс сборки, например, hello.o может быть построен из hello.c и hello может быть связан с hello.o и так далее, но он, конечно, не может догадаться, что libcs50 должны быть связаны в.

К счастью, правила неявного связывания содержат содержимое переменной LDLIBS в правильном, так что вы можете исправить это, написав простой Makefile в том же каталоге, содержащий только

LDLIBS += -lcs50

т.е. msgstr "добавить строку -lcs50 к текущему значению LDLIBS".

После этого make hello будет использовать неявные правила и новое значение LDLIBS для выполнения

cc     hello.c  -lcs50 -o hello

Также обратите внимание, что команда cc обычно это GCC, а не Clang, не то чтобы она имела значение в CS50. Его можно настроить с помощью переменной CC в Makefile:

CC := clang

Наконец, имеет смысл включить предупреждения и педантизм во флаги компиляции , например:

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.c и world.c, связанных вместе, вы можете получить с помощью неявные правила и просто утверждают, что helloworld зависит от обоих hello.o и world.o и должно быть связано вместе из них:

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

# the command must be indented by a *single* tab character, not spaces
...