libcs50 icon indicating copy to clipboard operation
libcs50 copied to clipboard

Can't link to libcs50

Open jacoboneill opened this issue 1 year ago • 1 comments

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.

jacoboneill avatar Jun 08 '24 18:06 jacoboneill

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

jp707049 avatar Jun 17 '24 16:06 jp707049

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:

  • cc
  • g++
  • clang
  • CommandLine Tools (they're constantly prompted for installation, despite being already installed)
  • All Java JVMs under Library/Java/JavaVirtualMachines (runtime error: "corrupted ZIP file")

stradicat avatar Aug 02 '24 20:08 stradicat

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:

  • if you use make cs50=1 it will link your file to the cs50 library
  • it will create a directory called build
  • it will compile all .c files in the current directory into it with the same name as the project, i.e. hello.c will compile to hello.out
  • if you run make clean it will remove the build directory

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.

jacoboneill avatar Aug 06 '24 15:08 jacoboneill