How to write a makefile both for a native compiler (g++ on Raspberry Pi), and for a crosscompiler (crosstool-ng)? - makefile

I've just run into the following issue: I've got a Raspi 3B with a GNU toolchain I normally use to build my C++ project on the Raspi itself. As my project has grown quite large, I would now prefer to cross-build it on my Linux PC with crosstool-ng installed. What I need, though, is a makefile, which both works with the toolchain on the Raspi, and the crosstool. This has been my makefile so far:
CC=g++
CFLAGS=-std=c++11 -ggdb -Wall -Wmultichar
LDFLAGS=-L/usr/lib -L/usr/lib/arm-linux-gnueabihf
LIBRARIES=-lpthread -lkeystonecomm -lgps -lpigpio -lGeographic -lmk4 -lcsvparser -lasound -lespeak -lmpg123 -lout123
SRC=main.cpp vfd.cpp relay.cpp keypad.cpp receiver.cpp widgets.cpp tmc.cpp database.cpp sound.cpp
OBJECTS=main.o vfd.o relay.o keypad.o receiver.o widgets.o tmc.o database.o sound.o
EXEC=autoradio
$(EXEC) : $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $(EXEC) $(LDFLAGS) $(LIBRARIES)
$(OBJECTS) : $(SRC)
$(CC) $(CFLAGS) -c $(SRC)
.PHONY: clean
clean:
rm -rf *.o $(EXEC)
The issue is the following: The crosscompiler is called arm-unknown-linux-gnueabi-g++, and the library paths are different. My goal, however, is to start the build process with a simple make command both on my Raspi, and on my host machine. Or will I have to use a configure script?
As I haven't found any useful tutorials on the Web, may anybody please help me. Thx.

OK, after consulting a few sources, I decided to implant a conditional into my makefile, which asks for the CPU environment variable. As Raspbian does not set it, I set the Raspi's architecture as a default. Et voilĂ , it works:
CPU?=armv7l
ifeq ($(CPU), armv7l)
CC=g++
else
CC=arm-unknown-linux-gnueabi-g++
endif
CFLAGS=-std=c++11 -ggdb -Wall -Wmultichar
ifeq ($(CPU), armv7l)
LDFLAGS=-L/usr/lib -L/usr/lib/arm-linux-gnueabihf
else
LDFLAGS=-L/usr/lib -L/opt/x-tools/arm-unknown-linux-gnueabi/lib
endif
LIBRARIES=-lpthread -lkeystonecomm -lgps -lpigpio -lGeographic -lmk4 -lcsvparser -lasound -lespeak -lmpg123 -lout123
SRC=main.cpp vfd.cpp relay.cpp keypad.cpp receiver.cpp widgets.cpp tmc.cpp database.cpp sound.cpp
OBJECTS=main.o vfd.o relay.o keypad.o receiver.o widgets.o tmc.o database.o sound.o
EXEC=autoradio
$(EXEC) : $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $(EXEC) $(LDFLAGS) $(LIBRARIES)
$(OBJECTS) : $(SRC)
$(CC) $(CFLAGS) -c $(SRC)
.PHONY: clean
clean:
rm -rf *.o $(EXEC)

Related

Makefile target gets called twice

I have the following Makefile:
VERSION = 0.1.1
CC = g++
CFLAGS = -Wall -g -DVERSION=\"$(VERSION)\"
LDFLAGS = -lm
DEPFILE = .dep
SOURCES := ${wildcard *.cpp}
HEADERS := ${wildcard *.h}
OBJECTS := ${SOURCES:.cpp=.o}
BINARY = main.exe
.PHONY: all dep clean
all: $(BINARY)
$(BINARY): $(DEPFILE) $(OBJECTS)
$(CC) $(CFLAGS) -o $(BINARY) $(OBJECTS) $(LDFLAGS)
%.o: %.cpp
$(CC) $(CFLAGS) -c $<
dep: $(DEPFILE)
$(DEPFILE): $(SOURCES) $(HEADERS)
$(CC) -MM $(SOURCES) > $(DEPFILE)
-include $(DEPFILE)
clean:
rm -vf $(BINARY) $(OBJECTS) $(DEPFILE)
When I run make dep I get
g++ -MM Monomial.cpp main.cpp Variable.cpp > .dep
make: Nothing to be done for 'dep'.
It seems as if dep is called twice. Why is that?
I am using GNU Make 4.2.1 under Cygwin.
Also it would be great if you could give me some best practises for this Makefile if you spot some bad design patterns (other than the double call of dep).
Your makefile contains an include directive:
-include $(DEPFILE)
So when Make starts, before it even considers the target(s) you've asked it to build, it tries to rebuild the file that is to be included in the makefile. Once it's done rebuilding .dep, it gets to work on the file you asked for... which is .dep.
You probably don't have to explicitly make dep, ever.
And you can simplify a couple of your rules in light of this fact, and the useful nature of automatic variables:
$(BINARY): $(OBJECTS)
$(CC) $(CFLAGS) -o $# $^ $(LDFLAGS)
$(DEPFILE): $(SOURCES) $(HEADERS)
$(CC) -MM $(SOURCES) > $#

Why I don't need to add prerequisite ".depend" in this make file?

I have a make file I wrote which represents a simple example of auto-detecting if a header file is changed using .depend generated by gcc -MM -MF.
Consider the following makefile: We have main.c and factorial.h
CC=gcc
CFLAGS=-c -Wall
OBJECTS=main.o
SRCS=main.c
EXECUTABLE=program
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) -o $(EXECUTABLE)
.depend: $(SRCS)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^ -MF ./.depend;
sinclude .depend
#main.o: main.c factorial.h
clean:
rm -rf *.o $(EXECUTABLE) .depend
This works fine and I want to know why!
The common sense is to write
$(EXECUTABLE): $(OBJECTS) .depend
because we want to make sure the file .depend is there. However, it seems like omitting it works fine, too. Why? Also, I'd like to know what include (or sinclude in this case) actually does. I think: in our example, include .depend would be replaced by
main.o: main.c factorial.h, but again the workflow doesn't make sense. Any experts?
Make will automatically try to remake the target of an include directive
[...]after reading in all makefiles, make will consider each as a goal target and attempt to update it.
The line sinclude .depend tells make "Read in .depend, don't quit if it fails, look for any matching rules, and remake .depend if it's out of date."
In any case you should create dependencies as a side effect of compilation, there's really no need for the extra step
target := program
sources := main.c
objs := $(sources:.c=.o)
deps := $(objs:.o=.d)
CPPFLAGS := -MMD -MP
CFLAGS := -Wall
$(target): $(objs)
$(LINK.o) $^ $(LDLIBS) -o $#
clean: ; $(RM) $(target) $(objs) $(deps)
-include $(deps)

How to write a makefile for llvm IR

If I have 3 files, function.h, function.c and my_program.c which calls a method in function.h all in the same directory, what would be the best way to write a makefile so that I end up with a my_program.bc that would actually run when I type in lli my_program.bc? (I need to run a user defined pass that would insert stuff into the functions - should I run the pass on function.bc and test.bc, or should I link before running the pass?)
I've tried llvm-link function.bc my_program.bc with no luck. I feel I'm either missing something simple or going about the whole thing wrong.
Current terrible none-working makefile:
.PHONY: all clean
CC = clang
CFLAGS = -std=gnu99 -D_POSIX_C_SOURCE=200809L -g -Wall
IRFLAGS = -O3 -emit-llvm
TARGET = test
DEPS = functions.h
all: $(TARGET)
bc: test2
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
%.bc: %.c $(DEPS)
$(CC) $(IRFLAGS) -c -o $# $<
test2: test.bc functions.bc
llvm-link -o test2.bc $< functions.bc
test: test.o functions.o
$(CC) $(CFLAGS) -o $# $^
clean:
$(RM) $(TARGET) *.o *.bc
Why not just write a normal Makefile to produce the desired executable,
then use wllvm?
Shameless plug for wllvm:
https://github.com/SRI-CSL/whole-program-llvm
I do not use lli, so I would be interested to hear about how it resolved
any reliance on stdlibc that your program may have.

CMake with CLion

I have been using Kdevelop with a project, now im on a different laptop, and need to build the project with CLion and MinGW on Windows.
I had this makefile (works on KDevelop)
CC=gcc
DEPS = cmp_micris_defs.h
OBJ = cmp_micris_datos_msc.o cmp_micris_rutinas.o cmp_micris_UnixSocket.o cmp_micris_cfg.o cmp_micris_db.o cmp_micris_TCP.o cmp_micris_utiles.o cmp_micris_datos.o cmp_micris.o
LIBS = -lpthread -lmysqlclient
.PREFIXES = .c .o
.c.o:
$(CC) -std=gnu99 -c -I/home/borja/projects/micris2/proceso-micris2/proceso/ $< $(LIBS)
cmp_micris_borja: $(OBJ)
$(CC) -o $# $(OBJ) $(LIBS)
all: cmp_micris_borja
clean:
rm -rf $(OBJ) cmp_micris_borja
But CLion use Cmake to build, i have not used it before, what should i write in CMakeLists.txt to build like before with my makefile ?
Thanks.

How can I put .o files to different folder and how should I improve this overall?

I've never really wrote any makefiles before and I have little knowledge of its syntax.
I'd like to put .o files into separate folder, obj/ for example. But I'm a bit lost how this should be done since there seem to be lot's of different ways to write makefile.
This is what I have currently and I would like to improve it.
PROGRAM=Project
CC=g++
CFLAGS=-c -g -std=c++0x -Wall -Wextra -pedantic -I $(SFML)/include -I src
LDFLAGS=-lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio -L $(SFML)/lib -Wl,-rpath=$(SFML)/lib -Wl,-rpath-link=$(SFML)/lib
SOURCES=$(wildcard src/*.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=bin/project
all: build $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
build:
#mkdir -p bin
clean:
rm -rf $(EXECUTABLE) $(OBJECTS)
I've tried some different approaches but haven't yet figured out how to put .o files in their own folder.
Replace your OBJECTS line with something like:
OBJECTS=$(patsubst src/%.cpp,obj/%.o,$(SOURCES))
Remove the .ccp.o rule and replace it with something like:
obj/%.o: src/%.cpp
$(CC) $(CFLAGS) $< -o $#
You can probably also remove $(SOURCES) from the prerequisite list of the all target unless you expect make to try to create those files somehow.

Resources