macOS llvm compilation : ld: library not found for -lomp - c

I have to use openMP for a project with my university. To do that I downloaded llvm using brew and I replaced cc = gcc in the makefile by CC=/usr/local/opt/llvm/bin/clang.
Now it seemed like it was going to work, but I get an unexpected error ld: library not found for -lomp clang-11: error: linker command failed with exit code 1.
When I run llvm-config --system-libs I get : -lm -lz -lcurses -lxml2.
I'm a complete beginner on this subject, but I think I have to install the ld library ?
Can anyone help ?
edit: full makefile
C=/usr/local/opt/llvm/bin/clang
CFLAGS = -O2 -fopenmp
LDFLAGS = -fopenmp
EXEC = bubble.run \
mergesort.run \
odd-even.run
HEADER_FILES = $(wildcard *.h)
RAND_INIT=0
ifeq ($(RAND_INIT), 1)
$(Initialization of the vector is random)
CONFIG_FLAGS += -DRINIT
endif
all: $(EXEC)
%.run: %.o utils.o
$(CC) $(LDFLAGS) -o $# $^
%.o: %.c $(HEADER_FILES)
$(CC) -c $(CONFIG_FLAGS) $(CFLAGS) $< -o $#
clean:
rm -f $(EXEC) *.o *~
.PHONY: clean

Solved in the comments by Craig Estey.
So here's my tutorial for compiling openMP on macOS.
install llvm with brew install llvm
install libomp with brew install libomp
Now, it clang and clang++ are calling llvm compilation, OpenMP should compile. But that's where I ran into the issue of missing ld linked.
use find /usr/local -xdev -name '*libomp*' to find where libomp is installed, probably at /usr/local/opt/libomp
Now when you compile/in your makefile, use clang instead of cc/gcc and add LDFLAGS += -L <YOUR PATH TO LIBOMP>/libomp/lib and CFLAGS += -I/usr/local/opt/libomp/include to your make file. Compiling should now work.

Related

usr/x86_64-unknown-linux-gnu/bin/ld: cannot find -lbsd

A little background for the problem I am having:
I just migrated from Ubuntu Focal Fossa to Mint Cinnamon keeping my home in a partition
libbsd is installed and can be used to compile some test code (I did a "Hello world" test using strlcpy in the main to verify that libbsd was usable)
Basically in order to use this project I have to use a library provided by my school (which compiled without problems in my last system) which is has a testing script that is going to run a test with its own Makefile:
INC=%%%%
INCLIB=$(INC)/../lib
UNAME := $(shell uname)
CFLAGS= -I$(INC) -O3 -I.. -g
NAME= mlx-test
SRC = main.c
OBJ = $(SRC:%.c=%.o)
LFLAGS = -L.. -lmlx -L$(INCLIB) -lXext -lX11 -lm
ifeq ($(UNAME), Darwin)
# mac
CC = clang
else ifeq ($(UNAME), FreeBSD)
# FreeBSD
CC = clang
else
#Linux and others...
CC = gcc
LFLAGS += -lbsd
endif
all: $(NAME)
$(NAME): $(OBJ)
$(CC) -o $(NAME) $(OBJ) $(LFLAGS)
clean:
rm -f $(NAME) $(OBJ) *~ core *.core
re: clean all
mlx would be the name of the library. For who is not familiar with this syntax (I was not) INC=%%%% is going to expand to /usr/include.
The command to compile the test binary expands to:
$ gcc -o mlx-test main.o -L.. -lmlx -L/usr/include/../lib -lXext -lX11 -lm -lbsd
which generates the error
/usr/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/../../../../x86_64-unknown-linux-gnu/bin/ld: cannot find -lbsd
(that path expands to usr/x86_64-unknown-linux-gnu/bin/ld)
Now, this kinda looks like a gcc configuration, in fact I saw something similar in the output of the command gcc --version -v, but only with x86_64-linux-gnu so without the "unkown" part. Also, one of the weird things is that the path that appears in the error actually does not exist in my system.
I already tried reinstalling gcc but with no different result.
I hope the description was clear enough, please let me know if you may need any other detail that I did not think of.

Writing a make file for GLFW3

i'm writing an emulator program and I need a graphics library. I have 4 files, the graphics library GLWF3 is installed in my includes folder. Im using MacOs Yosemite. I can't figure out how to get the makefile working though to include the glfw3 library. Thanks in advance!
Also note the only file including GLWF3 is graphics.h
Makefile
OBJ = graphics.o chip8.o
emulator: $(OBJ)
gcc -o emulator $(OBJ)
graphics.o: graphics.c graphics.h
gcc -c graphics.c
chip8.o: chip8.c chip8.h
gcc -c chip8.c
clean:
rm -f $(OBJ) emulator
To build with a given library, you have to:
tell the compiler how to find library header file
tell the linker which what library at must link.
Compilation
To tell where are the headers, you must pass a -I/path/to/dir option to gcc. Often, the make CFLAGS variable is used to do so:
CFLAGS= -I/path/to/glfw/include/dir
graphics.o: graphics.c graphics.h
gcc -c graphics.c $(CFLAGS)
chip8.o: chip8.c chip8.h
gcc -c chip8.c
Link
To tell linker what library to use, and where it is located, option -L/path/to/sofile and -lthelib are used. Usually in LDFLAGS variable:
Warning: The -l options must come after the files to link (*.o files)
LDFLAGS = -L/path/to/libglfw/lib/dir
# if the so file name is "libglfw3.so", the "-l" option must be "-lglfw3"
LDFLAGS += -lglfw3
emulator: $(OBJ)
gcc -o emulator $(OBJ) $(LDFLAGS)
pkg-config
To not to have to deal with paths, you can use pkg-config tool: This tool will help you to set CFLAGS and LDFLAGS variables. See here for installation instructions..
Hence, you makefile will looks like:
OBJ = graphics.o chip8.o
# calling program "pkg-config" and store result in CFLAGS variable
CFLAGS = $(shell pkg-config --cflags glfw3)
# calling program "pkg-config" and store result in LDFLAGS variable
LDFLAGS = $(shell pkg-config --ldflags glfw3)
emulator: $(OBJ)
gcc -o emulator $(OBJ) $(LDFLAGS)
graphics.o: graphics.c graphics.h
gcc $(CFLAGS) -c graphics.c
chip8.o: chip8.c chip8.h
gcc $(CFLAGS) -c chip8.c
clean:
rm -f $(OBJ) emulator

fedora 22 multiple undefined reference errors when linking shared object

I am trying to compile a C language library as a shared object on my new install of Fedora 22. The project compiled fine on my old install of Fedora 20. But now, when I run my makefile:
CC=gcc
vpath %.c src
vpath %.h inc
CFLAGS = -fPIC
INCLUDE = -Iinc -I/usr/include -I/usr/local/include
LIBPATH = -L/usr/lib -L/lib64
LIBS = -lportaudio -lm -lpthread -ldl
OBJ_PATH = ./objs
SRCS = my_code1.c my_code2.c # etc.
OBJS = $(SRCS:.c=.o)
.PHONY: libmylib.so
all: libmylib.so
debug: $(CFLAGS) += -DDEBUG -O0 -g3 -DPD
debug: all
release: $(CFLAGS) += -DTESTING -O2 -DPD -funroll-loops -fomit-frame-pointer
release: all
%.o: %.c
$(CC) $(CFLAGS) $(INCLUDE) $(LIBPATH) $(LIBS) -c -o $# $^
libmylib.so: $(OBJS)
$(CC) -shared -Wl,-soname,libmylib.so \
-Wl,--no-undefined $(OBJS) -lc -lportaudio -ldl -lm -lpthread
mv libmylib.so ./bin
mv *.o $(OBJ_PATH)
clean:
rm $(OBJ_PATH)/*.o
rm bin/libmylib.so
I get very many undefined reference errors:
my_code1.o: In function `func_in_my_code1':
my_code1.c:(.text+0x1b8): undefined reference to `func_from_my_code2'
my_code2.o: In function `func_in_my_code2':
my_code2.c:(.text+0x310): undefined reference to `func_from_my_func1'
The functions in question are most certainly defined in the code. Presumably these are compiled into .o files in the compile stage.
The exact same build environment worked on my previous fedora installation. I am at a loss as to why I should get these errors.
Also, if I compile without the -Wl,--no-undefined flag, it compiles fine, but when I try to load the library from another application, it tosses the same set of undefined errors.
This may have nothing to do with the new version of Fedora. It is possible that there are some environment variables or something that didn't make through to my new install, but I have no idea what they could be.
Apparently I now need to insert the extern keyword into these functions. The code compiled and ran perfectly well before... I would like to reiterate, for posterity's sake, that I did post the entire makefile in my question.

libevent problems with linking on ubuntu server 14.04

I have problem with linking libevent into my c project on ubuntu 14.04 LTS Server. Everything works fine on ArchLinux and Centos7 (both ubuntu and centos I run on virtual machine).
These is my Makefile:
TARGET: opoznienia
CFLAGS = -Wall -O2 --std=c11 -D DEBUG=1 $(shell pkg-config --cflags libevent_pthreads) -pthread -Wextra
LFLAGS = -Wall $(shell pkg-config --libs libevent_pthreads) -pthread -Wextra
OFILES = main.o err.o dropnobody.o ... <-- tl;tr
opoznienia: $(OFILES)
$(CC) $(LFLAGS) $^ -o $#
.PHONY: clean TARGET
clean:
rm -f opoznienia *.o *~ *.bak
On ubuntu I get error:
telnet_server.c:(.text+0xfc): undefined reference to `event_new'
GNU linker parses the object files arguments (.o .a .so) from left to right trying to match all the undefined symbols. And the order of object files is really important here, because GNU linker 'forgets' any symbols if they were not used by any object file passed in the argument list before the current object file.
In your case try changing the linkage order form:
$(CC) $(LFLAGS) $^ -o $#
To:
$(CC) $^ $(LFLAGS) -o $#
Let us know if this helps.

Adapt Makefile for cross-compilation

I have a makefile that works fine when I compile using /usr/bin/gcc to compile it. However I'm trying to compile it using a crosstool-ng compiler. I've changed CC to the cross-compilers location, and added a prefix to the directory that holds the compiler, but I get an error compiling.
The Makefile is here (sorry, it's long):
CFLAGS ?= -Wall -O0 -ggdb3
PREFIX = /home/me/crosstool-ng-1.18.0/x-tools/i586-system-linux-gnu/
CC = /home/me/crosstool-ng-1.18.0/x-tools/i586-system-linux-gnu/bin/i586-system-linux-gnu-gcc
ALL_CFLAGS = $(CFLAGS) -D_GNU_SOURCE
.phony: all
all: food libfood.so.1.0.0 foo_query
.phony: tools
tool tools: libfood_print foo_print
.phony: install
install: libfood.so.1.0.0
cp libfood.so.1.0.0 $(PREFIX)/lib
cd $(PREFIX)/lib ; \
ln -sf libfood.so.1.0.0 libfood.so.1 ; \
ln -sf libfood.so.1 libfood.so
cp libfood.h $(PREFIX)/include
cp foo_data.h $(PREFIX)/include
cp food $(PREFIX)/bin
cp foo_query $(PREFIX)/bin
%.o: %.c
$(CC) $(ALL_CFLAGS) -c $<
food: food.o foo.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lm -lpthread
libfood.so.1.0.0: libfood.o
$(CC) -shared -Wl,-soname,libfood.so.1 -o libfood.so.1.0.0 libfood.o
libfood_print: libfood_print.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lfood
foo_print: foo_print.o foo.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lm -lpthread
foo_query: foo_query.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lfood
food.o: food.c foo.h foo_data.h
foo.o: foo.c foo.h foo_data.h
foo_print.o: foo_print.c foo_data.h
foo_query.o: foo_query.c foo_data.h
libfood.o: libfood.c libfood.h
$(CC) $(ALL_CFLAGS) -fPIC -c $<
foo_print.o: foo_print.c foo.h
.phony:clean
clean:
rm -rf *.o *~ food libfood.so.1.0.0 foo_print libfood_print foo_query
The error message I'm getting says cannot find -lfood
collect2: ld returned 1 exit status
If anyone could suggest a fix for this I'd be very grateful.
EDIT: My Solution:
I should probably have been clearer but this Makefile was being used to build a package that was included in buildroot. I tried the suggestion by Jonatan, but unfortunately I still got the same error. My workaround was to run buildroot using make -k, and then build again using make.
An easy way to solve this would be:
ALL_CFLAGS += -L$(PREFIX)/lib
If you really want to install your lib in the toolchain, you should look for the usr/lib directory, usually the path is TOOLCHAIN_DIR/TOOLCHAIN_PREFIX/sysroot/usr/lib
Check other binaries in the $(PREFIX)/lib directory, you will notice that they were compile to run in you host, and not in your target.
The files the compiler need to check dependencies, link, and execute in your target, are installed in the sysroot directory.

Resources