Writing a make file for GLFW3 - c

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

Related

Fatal error when trying to set up fftw3 with c, MacOS Monterey

When trying to compile my c code I keep getting basic.c:5:10: fatal error: 'fftw3.h' file not found. I am compiling my c code using MacOS terminal and have Xcode installed.
I'm trying to write some c code which uses the fftw-3 library. fftw-3 has been installed using sudo port install fftw-3 and I have entered port contents fftw-3 which returned:
/opt/local/include/dfftw.h
/opt/local/include/dfftw_threads.h
/opt/local/include/drfftw.h
/opt/local/include/drfftw_threads.h
/opt/local/include/fftw_f77.i
/opt/local/lib/libdfftw.2.dylib
/opt/local/lib/libdfftw.a
/opt/local/lib/libdfftw.dylib
/opt/local/lib/libdfftw_threads.2.dylib
/opt/local/lib/libdfftw_threads.a
/opt/local/lib/libdfftw_threads.dylib
/opt/local/lib/libdrfftw.2.dylib
/opt/local/lib/libdrfftw.a
/opt/local/lib/libdrfftw.dylib
/opt/local/lib/libdrfftw_threads.2.dylib
/opt/local/lib/libdrfftw_threads.a
/opt/local/lib/libdrfftw_threads.dylib
/opt/local/share/info/fftw.info
/opt/local/share/info/fftw.info-1
/opt/local/share/info/fftw.info-2
/opt/local/share/info/fftw.info-3
/opt/local/share/info/fftw.info-4
/opt/local/share/info/fftw.info-5
I have been using a makefile and am trying to work out what needs including in it. At the moment I have:
# define the name of your source file(s)
SRCS = basic.c
# define the name of the object files(s) - we can do this automatically
OBJS = $(SRCS:.c=.o)
# tell MAKE which compiler to use
CCOMP = gcc
# flags for the compiler
# don't forget the -O3
CFLAGS = -Wall -O3 -fstrict-aliasing -Iinclude
#CFLAGS = -c -Wall -Iinclude
# flags for the linker. note -lm for the math library
LDFLAGS = -O3 -lm -L/opt/lib -I/opt/lib -L/opt/local/include -I/opt/lib
# the name of your executable file (the target) - here we put it in the top directory
TARGET = basic
# actions
all: $(OBJS)
$(CCOMP) -o $(TARGET) $(OBJS) $(LDFLAGS)
%.o: %.c
$(CCOMP) -c -o $# $< $(CFLAGS)
# delete all objects and target
clean:
rm -f $(OBJS) $(TARGET)
I'm not sure if the #CFLAGS and #LDFLAGS sections are correct? I would appreciate troubleshooting and any advice on what I need to do to get this working. Thanks!

How to find the library <openssl/des.c> and usit in C programs [duplicate]

I have built OpenSSL from source (an intentionally old version; built with ./config && make && make test) and would prefer to use what I have built without doing make install to link against my program.
The command that's failing is:
gcc -Wall -Wextra -Werror -static -Lopenssl/openssl-0.9.8k/ -lssl -lcrypto
-Iopenssl/openssl-0.9.8k/include -o myApp source1.o source2.o common.o`
And I receive a series of errors similar to:
common.c:(.text+0x1ea): undefined reference to `SSL_write'
This makes me think there's something funky with my OpenSSL. If I omit -Lopenssl/openssl-0.9.8k/ from my command, the error changes to being unable to:
/usr/bin/ld: cannot find -lssl
/usr/bin/ld: cannot find -lcrypto
Am I compiling OpenSSL incorrectly? Or how should I best resolve this?
Silly "Linux-isms" strike again! Apparently, I need to change my command such that the -L and -l stuff is at the end like (despite what man gcc seems to indicate):
gcc -Wall -Wextra -Werror -static -o myApp source1.o source2.o common.o -Lopenssl/openssl-0.9.8k/ -lssl -lcrypto -Iopenssl/openssl-0.9.8k/include
Why don't you want to use make install? It can copy generated binaries in the directory you want if you previously passed it to ./configure --prefix $HOME/target_library_install_directory
If you used this trick with every library you build and install, you could then add the target directory to the LIBRARY_PATH environment variable and avoid using -L option.
If you use Autotools, or you are building an Autools project like cURL, then you should be able to use pkg-config. The idea is the Autotools package will read OpenSSL's package configuration and things will "just work" for you.
The OpenSSL package configuration library name is openssl.
You would use it like so in a makefile based project.
%.o: %.c
$(CC) -o $# -c `pkg-config --cflags openssl` $^
target: foo.o bar.o baz.o
$(CC) -o $# `pkg-config --libs openssl` $^
Also see How to use pkg-config in Make and How to use pkg-config to link a library statically.
Another approach is to use pkg-config to preserve compatibility. This is an example of makefile when needs to link OpenSSL.
CC = gcc
CFLAGS = \
-I. \
-D_GNU_SOURCE=1
LDFLAGS = `pkg-config --libs inih`
LDFLAGS += `pkg-config --libs libcurl`
LDFLAGS += `pkg-config --libs liburiparser`
LDFLAGS += `pkg-config --libs openssl`
# Executable
foo: foo.o
$(CC) -o $# $^ $(LDFLAGS)
foo.o: foo.c
$(CC) -c $(CFLAGS) $< -o $#

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.

GCC exiting with an error 1 even with -Wall. No explanation why?

So I tried to recompile one of my projects from a few weeks ago and to my surprise I keep receiving an error one on it. I used MinGW to compile it originally and Eclipse CDT. I have -Wall flag enabled on GCC so I assumed if it was a problem with the code I would have a more useful information than a make error 1 being thrown. As such, I suspect that the issue could lie in how I formatted the make file. Luckily, I did compile the project when I push the commits last time and the binaries are still in the repo. Nevertheless, I would appreciate some help so that I can continue to improve
the project.
Edit: when I do -all, it just refuses to compile.
Here is the makefile. I hope it is a simple as me following some incorrect syntax:
CC=gcc -I../Include -L..\Lib
override CFLAGS+=-Wall -O3 #$(shell pkg-config --cflags fftw3)
#override LDFLAGS+=#$(shell pkg-config --libs fftw3 glib-2.0) -lm
.PHONY: all clean
all: lvdoenc lvdodec
lvdoenc: lvdoenc.o lvdomain.o
$(CC) $(CFLAGS) -o $# $^ $(LDFLAGS) -I../Include -L../Lib -lfftw3
lvdodec: lvdodec.o lvdomain.o
$(CC) $(CFLAGS) -o $# $^ $(LDFLAGS) -I../Include -L../Lib -lfftw3
%.o: %.c
$(CC) -c $(CFLAGS) -o $# $^
lvdoenc.c: lvdocommon.h
lvdodec.c: lvdocommon.h
clean:
rm -f lvdoenc lvdodec lvdomain.o lvdoenc.o lvdodec.o
Here is a link to my repo:
https://github.com/Skylion007/LVDOWin
Update: Using some of the answers I have confirmed that it is GCC that is exiting with an error 1 and I cannot figure out why.
Update2: It's not printing anything to syserr.
Without a transcript of make's output, when you run it, I can't see why GCC should fail silently, but I can see at least two problems with your makefile:
Since you state that you are using MinGW, your target platform must be MS-Windows, on which executable files should be qualified by a .exe extension; thus, your all: lvdoenc lvdodec rule is malformed; it should, at the very least be all: lvdoenc.exe lvdodec.exe[1], (or better, for portability all: lvdoenc$(EXEEXT) lvdodec$(EXEEXT), where you define EXEEXT = .exe for Windows, and leave EXEEXT undefined, or defined to be nothing, for platforms which don't require the extension).
Your two rules lvdoenc.c: lvdocommon.h and lvdodec.c: lvdocommon.h are obviously incorrect; the .c files don't depend on the .h, but their respective .o files do. Thus, these two rules should be lvdoenc.o: lvdocommon.h and lvdodec.o: lvdocommon.h respectively.
[1] Of course, you then also need to correctly refer to these two "goals" respectively, as lvdoenc.exe and lvdodec.exe, (or lvdoenc$(EXEEXT) and lvdodec$(EXEEXT)), consistently, throughout the makefile.
There are a few other constructs, within your makefile, which I consider questionable: CC shouldn't really be defined, with the -I../Include or -L..\Lib, (and why inconsistently / in the former, but \ in the latter? Both should be /). Conventionally, -I ... belongs in CPPFLAGS, and -L ... in LDFLAGS, with both CFLAGS and CPPFLAGS passed to the compiler, and normally all of CFLAGS, CPPFLAGS, and LDFLAGS passed to the compiler driver, when invoking the linker, (although, as others have noted in comments, the -I ... settings are strictly necessary when compiling .c to .o, while the -L ... settings are required only in the linking phase).
the following makefile is more in line with what you need for your project.
However, it does not use:
#$(shell pkg-config --libs fftw3 glib-2.0)
which you will need to re-add.
notice the usage of ':=' when defining macros, so the macro only needs to be evaluated once, rather than every time it is referenced.
the paths for the SHELL macro and the CC macro may need to be modified for your system.
SHELL := /usr/bin/sh
CC := /usr/bin/gcc
#CFLAGS := -c -Wall -Wextra -pedantic -std=c99 -O3 #$(shell pkg-config --cflags fftw3)
CFLAGS := -c -Wall -Wextra -pedantic -std=c99 -O3
# override LDFLAGS+=#$(shell pkg-config --libs fftw3 glib-2.0) -lm
LDFLAGS :=
SRCS := $(wildcard *.c)
ENCOBJS := lvdoenc.o lvdomain.o
DECOBJS := lvdodec.o lvdomain.o
.PHONY: all clean
all: lvdoenc lvdodec
lvdoenc: $(ENCOBJS)
$(CC) $(LDFLAGS) -o $# $(ENCOBJS) -L../Lib -lfftw3 -lm
lvdodec: $(DECOBJS)
$(CC) $(LDFLAGS) -o $# $(DECOBJS) -L../Lib -lfftw3 -lm
%.o:%.c lvdocommon.h
$(CC) -c $(CFLAGS) -c $< -o $# -I../Include
clean:
rm -f lvdoenc lvdodec lvdomain.o lvdoenc.o lvdodec.o
Apparently, all that was the cause was that I had uninstalled the 64bit version of MinGW and tried to switch to the 32bit version of MinGW. Unfortunately, some of the libraries would not compile in the 32bit version so I just used MinGW-w instead to solve this problem. It turns out GCC was not starting due to a linker error, but this error was not proportionating and could not be discovered until I tried to run it from the Windows terminal. I am still in the process of solving it and will update this answer when I have fully solved the issue.
Had the same problem while tried to compile my project with make from MSys. Accidentally problem had been solved, after I added a quotes to gcc input and output files in the makefile. I don't know how it works, but hope that it will help someone else.
So in the TS example code should look like this
%.o: %.c
$(CC) -c $(CFLAGS) -o "$#" "$^"
PS: had no problems with building project from ubuntu terminal though, so maybe it's just a msys problem.

Resources