I am trying to study cs50 on linux , I downloaded everything I found on github, but now I can not compile my first program with make, but I can use clang instead clang hello.c -lcs50 -o hello
which works just fine, but when I try to compile with make hello
I get
:~/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
I even moved the libcs50 folder that I downloaded to /usr/include/ but I still get the same results. after I compile with clang , and then excute make hello
it says make: 'hello' is up to date. I know it sounds dump but I am still newbie and looking for help. thanks in advance.
For linking in the cs50 library (which you should have installed from https://github.com/cs50/libcs50 according to the instructions there), your linking command should specify the -lcs50
argument.
make
usually needs a Makefile
to control the build. In its absence it can use some implicit rules to guess the build process, like that hello.o
could be built from hello.c
and hello
could be linked from hello.o
and so forth, but it certainly cannot guess that libcs50
should be linked in.
Fortunately, the implicit linking rules include the contents of the variable LDLIBS
in the correct, so you can fix this by writing a simple Makefile
in the same directory, containing just
LDLIBS += -lcs50
Ie "append the string -lcs50
to the current value of LDLIBS
".
After that make hello
will use the implicit rules and the new value of LDLIBS
to execute
cc hello.c -lcs50 -o hello
Also do note that the cc
command usually is GCC, not Clang, not that it should matter in CS50. It can be configured with the CC
variable in Makefile
:
CC := clang
Finally, it does make sense to enable warnings and pedantry in the compilation flags, for example:
CFLAGS += -Wall -Wextra -Werror -pedantic -std=c11
With all these 3 present, make hello
will actually execute
clang -Wall -Wextra -Werror -pedantic -std=c11 hello.c -lcs50 -o hello
which means we did save quite a lot typing and get more useful diagnostics!
Of course for a more complicated build process you'd need to write a more complicated Makefile
with dependency rules - say if your helloworld
program consisted of hello.c
and world.c
linked together you could get by the implicit rules and just state that helloworld
depends on both hello.o
and world.o
and should be linked together from these:
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.
Just make new Makefile in the dir where is your *.c file:
$ touch Makefile
Then just add this strings to your Makefile:
CC=clang
CFLAGS=-fsanitize=signed-integer-overflow -fsanitize=undefined -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow
LDLIBS=-lcrypt -lcs50 -lm
Than you can compile *.c file just typing:
$ make hello.c
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.