简体   繁体   中英

How to build CS50 programs with make

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM