Makefile for Linux and Mac with address sanitizer - linux

I am trying to write a makefile that I can use on linux and mac that builds with an address sanitizer. This works on my vagrant instance:
CC = gcc
ASAN_FLAGS = -fsanitize=address -fno-omit-frame-pointer -Wno-format-security
ASAN_LIBS = -static-libasan
CFLAGS := -Wall -Werror --std=gnu99 -g3
LDFLAGS += -lpthread
all: hello
hello: tiny_queue.o hello.o
$(CC) -o $# $(CFLAGS) $(ASAN_FLAGS) $(CURL_CFLAGS) $^ $(LDFLAGS) $(CURL_LIBS) $(ASAN_LIBS)
This works on ubuntu/trusty64 but fails on my mac with
$ make
gcc -Wall -Werror --std=gnu99 -g3 -I/opt/X11/include -c -o hello.o hello.c
gcc -o hello -Wall -Werror --std=gnu99 -g3 -fsanitize=address -fno-omit-frame-pointer -Wno-format-security tiny_queue.o hello.o -lpthread -static-libasan
clang: error: unknown argument: '-static-libasan'
make: *** [hello] Error 1
Does anyone know how to write a compatible makefile for the mac and linux?
p.s. I'm very new to C, sorry if this question is super basic.

CC = gcc
ASAN_FLAGS = -fsanitize=address -fno-omit-frame-pointer -Wno-format-security
ASAN_LIBS = -static-libasan
CFLAGS := -Wall -Werror --std=gnu99 -g3
LDFLAGS += -lpthread
all: hello
hello: tiny_queue.o hello.o
$(CC) -o $# $(CFLAGS) $(ASAN_FLAGS) $(CURL_CFLAGS) $^ $(LDFLAGS) $(CURL_LIBS) $(ASAN_LIBS)
You should not specify an Asan library (or a UBsan library, for that matter). Since you are using the compiler driver to drive link, just use -fsanitize=address (this is the recommended way of doing it). Do not add -static-libasan. The compiler driver will add the proper libraries for you.

Related

How does make use variables when expanding and compiling before linking?

Info:
Linux watvde0453 3.10.0-1062.1.1.el7.x86_64 #1 SMP Fri Sep 13 22:55:44 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
GNU Make 4.2.1
Built for x86_64-pc-linux-gnu
Hi
I have been playing around with a make file to allow builds of shared, static libraries and an exe (and also to get some sort of understanding about how it works) and came across some behavior I do not understand.
I was trying to separate out the flags used for lib / exe into separate variables, but when using a line to compile and link all in one it looks like only the CFLAGS variable is being included for the compile step.
When using the following makefile:
LIBCFLAGS := -fPIC
CFLAGS := -O3 -g -Wall -Werror
CC := gcc
SRCS=hashfunction.c hashtable.c hashtablelinkedlist.c
OBJS=hashfunction.o hashtable.o hashtablelinkedlist.o
LIBSO = lib$(NAME).so
libso: $(OBJS)
$(CC) $(LIBCFLAGS) $(CFLAGS) -shared -o $(LIBSO) $(OBJS)
I get the following output when running the make command for libso:
$ make libso
gcc -O3 -g -Wall -Werror -c -o hashfunction.o hashfunction.c
gcc -O3 -g -Wall -Werror -c -o hashtable.o hashtable.c
gcc -O3 -g -Wall -Werror -c -o hashtablelinkedlist.o hashtablelinkedlist.c
gcc -fPIC -O3 -g -Wall -Werror -shared -o lib.so hashfunction.o hashtable.o hashtablelinkedlist.o
/tools/oss/packages/x86_64-centos7/binutils/default/bin/ld: hashtable.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
hashtable.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
make: *** [Makefile:12: libso] Error 1
I can get it all working by sticking all the flags in CFLAGS, but I was wondering if anyone could explain what make is doing underneath ?
It looks like the $(LIBCFLAGS) is being ignored for the implicit compile lines, but $(CFLAGS) is not. Is CFALGS used implicitly by make for all compilations ?
You can see all the built-in rules make knows about by running make -p -f/dev/null. There you'll see:
%.o: %.c
# recipe to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
which is the built-in rule make uses to create a .o file from a .c file. Looking elsewhere in the output you'll see:
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
so these are the variables make uses to compile .c files into .o files.

c++ makfile error: makefile:5: *** missing separator. Stop

I'm trying to run my c++ (written in clion) program in linux. When I try to compile it in the terminal using "make" command, I get this error:
"makefile:5: *** missing separator. Stop."
I already checked that there tabs and not 4 spaces in my makefile.
Anyone has an idea?
Thanks!
This is my makefile:
CFLAGS := -c -Wall -Weffc++ -g -std=c++11 -Iinclude
LDFLAGS := -lboost_system
all: StompBookClubClient
g++ -pthread -o bin/StompBookClubClient bin/ConnectionHandler.o bin/Book.o bin/keyboardInputSend.o bin/socketReader.o bin/User.o $(LDFLAGS)
StompBookClubClient: bin/StompBookClubClient bin/ConnectionHandler.o bin/Book.o bin/keyboardInputSend.o bin/socketReader.o bin/User.o
bin/Book.o: src/Stomp/Book.cpp
g++ -pthread $(CFLAGS) -o bin/Book.o src/Book.cpp
bin/ConnectionHandler.o: src/Stomp/ConnectionHandler.cpp
g++ -pthread $(CFLAGS) -o bin/ConnectionHandler.o src/ConnectionHandler.cpp
bin/keyboardInputSend.o: src/Stomp/keyboardInputSend.cpp
g++ -pthread $(CFLAGS) -o bin/keyboardInputSend.o src/keyboardInputSend.cpp
bin/socketReader.o: src/Stomp/socketReader.cpp
g++ -pthread $(CFLAGS) -o bin/socketReader.o src/socketReader.cpp
bin/StompBookClubClient.o: src/Stomp/StompBookClubClient.cpp
g++ -pthread $(CFLAGS) -o bin/StompBookClubClient.o src/StompBookClubClient.cpp
bin/User.o: src/Stomp/User.cpp
g++ -pthread $(CFLAGS) -o bin/User.o src/User.cpp
.PHONY: clean
clean:
rm -f bin/*
I already checked that there tabs and not 4 spaces in my makefile.
Check it a bit harder. The Makefile you pasted here has 4 spaces on line 5 and produces exactly the error you are seeing. If I replace them by a tab, the next error occurs on line 10, and so on.
This is not an answer but I do not have sufficient points to comment and hence answering.
Apart from 'tab' issue ,you get a similar error if ':'(colon) is missed after the rule name.
Ex makefile:
helloworld.o
g++ helloworld.cc -o helloworld.o;
Error:
Makefile:1: *** missing separator. Stop.
Solution:
Colon after helloworld.o like below
helloworld.o:
g++ helloworld.cc -o helloworld.o;

Makefile for OpenGL with glad on Linux

I want to use glad in my OpenGL project but I am not quite sure how to create the Makefile for it. I downladed glad from the webservice and moved the directories from include/ (glad/ and KHR/) to /usr/include/ (Now emacs sees the library) and the glad.c file to the root of my project (which at the moment contatns only a demo source.cpp file).
I have this Makefile:
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Linux)
COMPILER = g++
FLAGS = -std=c++1y -pedantic -Wall
GL_FLAGS = -lGL -lglfw
endif
ifeq ($(UNAME_S), Darwin)
COMPILER = clang++
FLAGS = -std=c++1y -stdlib=libc++ -pedantic -Wall
GL_FLAGS = -lGLEW -framework OpenGL -lm
endif
FILES = $(wildcard *.cpp)
APP_NAME = opengl-app
all: main
main: $(FILES)
$(COMPILER) $(FLAGS) $(FILES) glad.c -o $(APP_NAME) $(GL_FLAGS)
.PHONY: clean run
clean:
rm opengl-app
run: opengl-app
./opengl-app
This when executed gives these errors:
/usr/bin/ld: /tmp/cc0DUjDZ.o: undefined reference to symbol 'dlclose##GLIBC_2.2.5'
/usr/lib/libdl.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Any help with the makefile will be greatly appreciated.
As mentioned in the comments by #G.M. glad makes use of dlopen/dlclose, methods used to load shared objects in Linux.
The Makefile should add the link flag to use libdl.so. The final result should be something like this:
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Linux)
COMPILER = g++
FLAGS = -std=c++1y -pedantic -Wall
GL_FLAGS = -lGL -lglfw
endif
ifeq ($(UNAME_S), Darwin)
COMPILER = clang++
FLAGS = -std=c++1y -stdlib=libc++ -pedantic -Wall
GL_FLAGS = -lGLEW -framework OpenGL -lm
GLAD_FLAGS = -ldl
endif
FILES = $(wildcard *.cpp)
APP_NAME = opengl-app
all: main
main: $(FILES)
$(COMPILER) $(FLAGS) $(FILES) glad.c -o $(APP_NAME) $(GL_FLAGS) $(GLAD_FLAGS)
.PHONY: clean run
clean:
rm opengl-app
run: opengl-app
./opengl-app

How to build a user level program in parallel with building Linux kernel

I have a set of kernel source files in ~linux/fs/wrapfs/. Besides, there is also a source file present for a user level program. I want to build that user level program while the kernel gets compiled by running "make" in ~/linux folder i.e in the top level kernel directory.
So, I tried adding following in ~/linux/fs/wrapfs/Makefile:
EXTRA_CFLAGS += prog
prog:
gcc -Wall -Werror prog.c -o prog -lssl -lcrypto
But, then everytime I do "make" in ~/linux, I get following error:
gcc: prog: No such file or directory
I then tried changing it to following but nothing helped:
EXTRA_CFLAGS += prog
all:
gcc -Wall -Werror prog.c -o prog -lssl -lcrypto
EXTRA_CFLAGS += prog
prog:
gcc -Wall -Werror ./fs/wrapfs/prog.c -o ./fs/wrapfs/prog -lssl -lcrypto
Please suggest how can this be solved.
You should not be trying to pass prog in CFLAGS, extra or otherwise.

Linking OpenSSL libraries to a program

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 $#

Resources