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.
I have a problem with GDB in Archlinux:
Even I add -g in my Makefile gdb say (no debugging symbols found)...done..
But if I compile manually gcc -g *.c it work...
I don't know what is don't work in my Makefile ?
My Archlinux:
Linux sime_arch 4.13.4-1-ARCH #1 SMP PREEMPT Thu Sep 28 08:39:52 CEST 2017 x86_64 GNU/Linux
My GCC:
gcc version 7.2.0 (GCC)
My Makefile:
SRC = test.c \
test2.c
OBJ = $(SRC:.c=.o)
NAME = test_name
CFLAG = -Wall -Werror -Wextra
all: $(NAME)
$(NAME): $(OBJ)
gcc -g $(OBJ) -o $(NAME) $(CFLAG)
clean:
rm -f $(OBJ)
fclean: clean
rm -f $(NAME)
re: fclean all}
Thanks in advance
You are adding the -g only to the linking command. The object files are generated by the auto compile target of make. This doesn't have the -g flag in it.
You have 2 options -
Change your variable CFLAG to CFLAGS and add -g to it. CFLAGS is picked by the auto compile command and it will create object files with debug info
Add the following target -
%.o: %.c
gcc -g $(CFLAG) -o $# $<
before the $(NAME) target.
The second one gives you more control with the targets but the first method is the standard way of compiling.
Also, always try using standard names for variables unless you specifically need to name them separately.
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
I am trying to write a makefile which uses macros to create multiple executables from multiple files at once. I tried searching through previously answered questions but, because I am fairly new to programming in C as well as working with gcc, I was not able to find an answer to my question.
Here is what I have so far:
CC=gcc
CFLAGS=-I.
OBJ = ex1.c ex3.c
EXECUTABLE = ex1 ex3
$(EXECUTABLE): $(OBJ)
gcc -o $# $^ $(CFLAGS)
clean:
rm -f $(EXECUTABLE)
I would like the line
$(EXECUTABLE): $(OBJ)
to create executables ex1 and ex3 from files ex1.c ex3.c respectively.
For this particular case, where each executable has a single source file with .c extension, all you need is a one line Makefile:
all: ex1 ex3
The built-in default rules for make then work already:
$ make
cc -O2 -pipe ex1.c -o ex1
cc -O2 -pipe ex3.c -o ex3
Behind the scene, make is using the POSIXly mandated built-in single suffix rule
.c:
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $<
Vary the command to your liking with make CC=gcc CFLAGS=-O2 LDFLAGS=-s and similar.
Trivia of the day: in fact, if you are willing to name the targets when invoking make, you can use an empty or even run without any Makefile:
$ make -f /dev/null CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3
gcc -O2 -s ex1.c -o ex1
gcc -O2 -s ex3.c -o ex3
$ rm -f Makefile ex1 ex3
$ make CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3
gcc -O2 -s ex1.c -o ex1
gcc -O2 -s ex3.c -o ex3
Make magic!
As a rule of thumb, don't reinvent the wheel (or rules), use the rules that are already there. It simplifies your and make's life a lot. This makes for small and sexy makefiles to impress the ladies with :-)
Some suggestions (assuming you use GNU make, not something else)
First, run once make -p, you'll understand what builtin rules make is knowing. Look in particular for COMPILE.c and LINK.c
Then, I suggest
CFLAGS= -g -Wall -I.
(because you really want -g for debugging, and -Wall to get most warnings)
And you probably don't need
$(EXECUTABLE): $(OBJ)
gcc -o $# $^ $(CFLAGS)
However, I suggest adding before most other rules
.PHONY: all clean
all: $(EXECUTABLES)
Actually, I would code your Makefile (for GNU make!) as follow
# file Makefile
CC= gcc
RM= rm -vf
CFLAGS= -Wall -g
CPPFLAGS= -I.
SRCFILES= ex1.c ex2.c ## or perhaps $(wildcard *.c)
OBJFILES= $(patsubst %.c, %.o, $(SRCFILES))
PROGFILES= $(patsubst %.c, %, $(SRCFILES))
.PHONY: all clean
all: $(PROGFILES)
clean:
$(RM) $(OBJFILES) $(PROGFILES) *~
## eof Makefile
Remember that tab is a significant character in Makefile-s (action part of rules). In this answer, lines starting with four spaces at least should really start with a tab character.
Once everything is debugged consider running make clean to clean everything, and then make -j CFLAGS=-O2 all to compile in parallel everything with optimizations.
At last, I recommend using remake and running remake -x to debug complex Makefile-s
Of course, I'm supposing that your directory has only single-file programs.
BTW, there are other build automation tools. Perhaps you might consider using omake or ninja. For building large programs (millions of source code lines) consider also automake, ccache, cmake, icecream. In some cases, consider generating some C code with GPP, GNU bison, SWIG, etc... or using your own Python or Guile script (or C meta-program). See also this draft report.
Don't forget to use a version control system like git for your source files. It is also time to learn such a tool.
The following answer includes multiple executable such as initiate, process1, process2, ..., process4.
LOCAL_INCLUDE=./
all: clean process_first process_second init
process_first:
gcc -g -o process1 -I$(LOCAL_INCLUDE) process1.c -lzmq -L. -L./.
gcc -g -o process2 -I$(LOCAL_INCLUDE) process2.c -lzmq -L. -L./.
process_second:
gcc -g -o process3 -I$(LOCAL_INCLUDE) process3.c -lzmq -L. -L./.
gcc -g -o process4 -I$(LOCAL_INCLUDE) process4.c -lzmq -L. -L./.
init:
gcc -g -o initiate -I$(LOCAL_INCLUDE) initiate.c -lzmq -lconfig -lpthread -L. -L./. -ldl -lrt
clean:
rm -rf init_manager.o init_manager
rm -rf process1 process2 process3 process4
NOTE: It is a good practice to clean and touch all the executable files before making them again.
You're close, but you need a pattern rule:
$(EXECUTABLE): % : %.c
And then a default rule to make it build both:
all: $(EXECUTABLE)
I am beginner when it comes to writing makefiles but I am having this linking issue with my program. Basically I am getting the above error when I try to build it on a remote machine.
Here is my makefile:
SRCS = gt_cfs.c gt_kthread.c gt_matrix.c gt_pq.c gt_signal.c gt_spinlock.c \
gt_uthread.c red_black_tree.c stack.c misc.c
HDRS = gt_bitops.h gt_cfs.h gt_include.h gt_kthread.h gt_pq.h gt_signal.h \
gt_tailq.h gt_uthread.h red_black_tree.h stack.h misc.h
OBJS = gt_cfs.o gt_kthread.o gt_matrix.o gt_pq.o gt_signal.o gt_spinlock.o \
gt_uthread.o red_black_tree.o stack.o misc.o
CC = gcc
CFLAGS = -Wall -pedantic -lrt -lm
PROGRAM = cfs_gtthreads
.PHONY: clean
all: $(PROGRAM)
$(PROGRAM): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(PROGRAM)
gt_include.h: gt_bitops.h gt_cfs.h gt_kthread.h gt_pq.h \
gt_signal.h gt_tailq.h gt_uthread.h
gt_cfs.o: gt_cfs.c
gt_kthread.o: gt_kthread.c
gt_matrix.o: gt_matrix.c
gt_pq.o: gt_pq.c
gt_signal.o: gt_signal.c
gt_spinlock.o: gt_spinlock.c
gt_uthread.o: gt_uthread.c
red_black_tree.o: red_black_tree.c
stack.o: stack.c
clean:
rm -f *.o *~ $(PROGRAM)
Now this code WORKS on my laptop but I have to run my program on a remote machine through SSH. Anyway on that machine is where I get this error, so I am confused as to why it can't link the two libraries: math and time (-lm and -lrt). The gcc versions are different, mine is 4.5.2 and the cluster machine is 4.1.2. I am also running mine on Ubuntu and the cluster machine is Red-Hat. I don't know what differences would cause this error since those are standard libraries. Any help is appreciated.
Thanks in advance.
Try using a LDFLAGS variable with -lrt -lm and put $(LDFLAGS) after the $(OBJS).
Try to put $(CFLAGS) in the end of the line. Sometimes it helps.