cs50 / libcs50

This is CS50's Library for C.
https://cs50.readthedocs.io/libraries/cs50/c/
GNU General Public License v3.0
1.74k stars 853 forks source link

Can't link to libcs50 #331

Closed jacoboneill closed 1 month ago

jacoboneill commented 3 months ago

Running on an intel mac, after running sudo make install on the library, and compiling a basic c file:

#include <cs50.h>
#include <stdio.h>

int main(){
  string res = get_string("> ");
  printf("%s", res);
}

I get an error that it can't load the library libcs50-11.0.2.dylib (I run clang main.c -o ./a.out -lcs50)

dyld[67961]: Library not loaded: libcs50-11.0.2.dylib
  Referenced from: <2CE4BD41-8453-3EDB-BBF4-70AD89B6C454> /Users/jacoboneill/Programming/cs50x/01/notes/user_input/a.out
  Reason: tried: 'libcs50-11.0.2.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibcs50-11.0.2.dylib' (no such file), 'libcs50-11.0.2.dylib' (no such file), '/Users/jacoboneill/Programming/cs50x/01/notes/user_input/libcs50-11.0.2.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/Users/jacoboneill/Programming/cs50x/01/notes/user_input/libcs50-11.0.2.dylib' (no such file), '/Users/jacoboneill/Programming/cs50x/01/notes/user_input/libcs50-11.0.2.dylib' (no such file)
[1]    67961 abort      ./a.out

After trying all the troubleshooting steps (setting C_INCLUDE_PATH, LD_LIBRARY, LIBRARY_PATH) nothing seems to help. I found a hacky way by running ln -s /usr/local/lib/libcs50-11.0.2.dylib ./libcs50-11.0.2.dylib (as it said it tried to search for it in the local folder in the debug). This works but I feel as though probably not the intended way to do it.

I can't tell if I did something wrong, or if there is something wrong with libcs50's makefile.

jp707049 commented 3 months ago

Hi @jacoboneill , I had the same issue on my mac and added the following in my .zshrc file

export DYLD_LIBRARY_PATH="/usr/local/lib:$DYLD_LIBRARY_PATH"

After adding that, I restarted my terminal and build the code. It worked. Hope this helps.

Thanks to - https://github.com/cs50/libcs50/issues/324#issuecomment-2098121474

stradicat commented 2 months ago

Hi @jacoboneill , I had the same issue on my mac and added the following in my .zshrc file

export DYLD_LIBRARY_PATH="/usr/local/lib:$DYLD_LIBRARY_PATH"

After adding that, I restarted my terminal and build the code. It worked. Hope this helps.

Thanks to - #324 (comment)

This does indeed solve the CS50 lib problem, but apparently in macOS Ventura 13.6.8 (x86_64) it breaks:

jacoboneill commented 1 month ago

The solution I ended up coming up with was to install a copy of the libcs50 library, and then link it and use a custom Makefile

Install libcs50

git clone https://github.com/cs50/libcs50.git
cd libcs50
sudo make install

Makefile

CC = gcc
SRCS := $(wildcard *.c)
TARGETS := $(SRCS:.c=.out)

cs50 = 0
LIB_PATH = **[ABSOLUTE PATH TO LIBRARY]**
DYLIB_NAME = **[NAME OF DYLIB]**
LIB_NAME = cs50
LIB_SYM_PATH = $(LIB_PATH)/lib/$(DYLIB_NAME)
LIB_CFLAGS = -I$(LIB_PATH)/include -L$(LIB_PATH)/lib -l$(LIB_NAME)

CFLAGS = -Wall -Werror
ifeq ($(cs50), 1)
    CFLAGS += $(LIB_CFLAGS)
endif

BUILD_DIR := ./build

all: $(TARGETS)

%.out: %.c
    @mkdir -p $(BUILD_DIR)
    $(CC) $(CFLAGS) -o $(BUILD_DIR)/$@ $<
    @if [ $(cs50) -eq 1 ]; then $(MAKE) symlink; fi

symlink:
    @ln -fs $(LIB_SYM_PATH) $(BUILD_DIR)/$(DYLIB_NAME)

clean:
    rm -rf $(BUILD_DIR)

.PHONY: all clean symlink

This will do the following when you run make in a dir:

So, I would use a bash script to make my workflow easier:

run

#!/bin/bash

bin="${1%.c}.out"
shift 1
clear; make && cd build; ./$bin "$@"; cd ..

(don't forget to chmod it: chmod +x ./run) Which would then let me run (for example on a file called hello.c) ./run hello.c. This would then clear the screen, make the new file, run the file and put me back in the directory i was in before.

The one thing I never figured out was how to run the compiled file outside the build dir. I found something to do with static lib files but could never get it working so this was the best that I could do. By week 4 I wasn't really using the library anymore anyway so kinda forgot about it.

This is definetley something that only experienced developers comfortable with config files should attempt, but I learned a lot. I'm going to close the issue for now as I think this is a pretty good workaround, definetley with the problems that @stradicat mentioned about @jp707049 's solution.