How to compile arduino core library with makefile? - c++

I want to create library files (.a) of the arduino core library, eventually also the other libraries (SPI, ...), with a makefile, but I can't get it to work!
This is my makefile:
CC=avr-gcc
CPP=avr-g++
MCU=-mmcu=atmega328p
CPU_SPEED=-DF_CPU=16000000UL
CFLAGS=$(MCU) $(CPU_SPEED) -g2 -gstabs -Os -Wall \
-ffunction-sections -fdata-sections -fno-exceptions
INCLUDE=-I./arduinoCORE
CFILES=$(wildcard ./arduinoCORE/*.c)
CPPFILES=$(wildcard ./arduinoCORE/*.cpp)
OBJ=$(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
default: $(OBJ)
avr-ar -r libarduinoUNO.a $^
%.o : %.c
$(CC) $< $(CFLAGS) -c -o $#
%.o : %.cpp
$(CPP) $< $(CFLAGS) -c -o $#
(all header and source files are in arduinoCORE; even pins_arduino.h)
After $ make in directory above arduinoCORE I get this error message:
avr-g++ arduinoCORE/CDC.cpp -mmcu=atmega328p -DF_CPU=16000000UL -g2 -gstabs -Os -Wall -ffunction-sections -fdata-sections -fno-exceptions -c -o arduinoCORE/CDC.o
In file included from arduinoCORE/Print.h:27:0,
from arduinoCORE/Stream.h:26,
from arduinoCORE/HardwareSerial.h:28,
from arduinoCORE/Arduino.h:193,
from arduinoCORE/Platform.h:15,
from arduinoCORE/CDC.cpp:19:
arduinoCORE/Printable.h:23:17: fatal error: new.h: No such file or directory
#include <new.h>
^
compilation terminated.
make: *** [arduinoCORE/CDC.o] Error 1
The problem is, that new.h is actually in arduinoCORE!
Does anyone know how to manage this?

I had a different error with your code. It displayed Arduino.h as not being present. I fixed it after actually adding the INCLUDE variable to CFLAGS and CPPFLAGS (yours was defined but not added).
I also used CFLAGS and CPPFLAGS as per the Arduino Specification. The code is:
CC=avr-gcc
CPP=avr-g++
MCU=-mmcu=atmega328p
CPU_SPEED=-DF_CPU=16000000UL
INCLUDE=-I./
CFLAGS = -c -g -Os -w -ffunction-sections -fdata-sections -MMD $(MCU) $(CPU_SPEED) $(INCLUDE)
CPPFLAGS = -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD $(MCU) $(CPU_SPEED) $(INCLUDE)
CFILES=$(wildcard ./*.c)
CPPFILES=$(wildcard ./*.cpp)
OBJ=$(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
default: $(OBJ)
avr-ar rcs core.a $^
%.o : %.c
$(CC) $< $(CFLAGS) -c -o $#
%.o : %.cpp
$(CPP) $< $(CPPFLAGS) -c -o $#
Which creates the archive successfully (not tested, just created).

Related

GNU Make: A better way of using both C/C++ targets with different commands

Q: Here is my Makefile fragment below:
SRCS+=$(wildcard *.c *.cpp)
OBJECTS=$(addprefix $(OBJ_DIR)/, $(patsubst %.c,%.o,$(SRCS:.cpp=.o)))
# .....
$(OBJ_DIR)/%.o: %.cpp
$(CXX) -ggdb -Wall -Wextra -Werror $(INC) $(C_FLAGS) -c -o $# $<
$(OBJ_DIR)/%.o: %.c
$(CC) -ggdb -Wall -Wextra -Werror $(INC) $(C_FLAGS) -c -o $# $<
How can I refactor expression after "OBJECTS" and remove duplication of the similar rules for .cpp and .%c?
OBJECTS := $(patsubst %,$(OBJ_DIR)/%.o,$(basename $(SRCS)))
# Note that you may not need this variable at all.
COMPILE_ARGS = -ggdb -Wall -Wextra -Werror $(INC) $(C_FLAGS) -c -o $# $<
$(OBJ_DIR)/%.o: %.cpp
$(CXX) $(COMPILE_ARGS)
$(OBJ_DIR)/%.o: %.c
$(CC) $(COMPILE_ARGS)

OpenMP Makefile, -fopenmp won't work

I'm trying to compile my project using a Makefile, but somehow the -fopenmp flag won't work.
Here's the Makefile:
TARGET=isaac
CC=g++
CFLAGS=-Wall -O2 -fopenmp
LDFLAGS=-lm -lpthread -lrt
OBJ=src/main.o src/bhtree.o src/body.o src/configreader.o src/diagnostics.o src/output.o src/quad.o src/timing.o src/vector2.o
isaac: $(OBJ)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJ) $(LDFLAGS)
%.o: src/%.cpp
$(CC) $(CFLAGS) -c $<
clean:
rm src/*.o src/*~ isaac
and here is the output when calling "make"
g++ -c -o src/main.o src/main.cpp
g++ -c -o src/bhtree.o src/bhtree.cpp
g++ -c -o src/body.o src/body.cpp
g++ -c -o src/configreader.o src/configreader.cpp
g++ -c -o src/diagnostics.o src/diagnostics.cpp
g++ -c -o src/output.o src/output.cpp
g++ -c -o src/quad.o src/quad.cpp
g++ -c -o src/timing.o src/timing.cpp
g++ -c -o src/vector2.o src/vector2.cpp
g++ -Wall -O2 -fopenmp -o isaac src/main.o src/bhtree.o src/body.o src/configreader.o src/diagnostics.o src/output.o src/quad.o src/timing.o src/vector2.o -lm -lpthread -lrt
the -fopenmp flag is missing when the source files are compiled, so the finished executable is serial, not parallel.
How can I fix this?
The problem is that your rule does not apply at all. You are free to remove
%.o: src/%.cpp
$(CC) $(CFLAGS) -c $<
and you'll get the same result as before. That's because some predefined rule is used instead of yours (I'm not great makefile expert though).
The core of the problem is that your rule is for ./*.o files, but you need ./src/*.o for isaac. You can change your rule
src/%.o: src/%.cpp
$(CC) $(CFLAGS) -c $<
Or (better) move all autogenerated staff somewhere from src.

Makefile for shared library that only compiles changed files?

I am working on a project where I am creating a .so object as my output that contains several operators for use in another program. I was given a Makefile that works just fine, except it always recompiles every file whenever I run make. Originally this was not an issue, but now that there are upwards of five or more operators in the library, running make is prohibitively slow. The trouble is that for the life of me, I can't figure out how to change this Makefile into one that behaves the way I want since I've never dealt with Makefiles in this format before:
BOOST_LOCATION=/usr/local/boost_1_54_0
CFLAGS=-pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -D__STDC_FORMAT_MACROS -Wno-system-headers -isystem -O2 -g -DNDEBUG -ggdb3 -D__STDC_LIMIT_MACROS
INC=-I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
LIBS=-L"$(IN_SOURCE_DIR)/lib" -shared -Wl,-soname,libname.so -L. -lm
all:
#if test ! -d "$(IN_SOURCE_DIR)"; then echo "Error. Try:\n\nmake IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>"; exit 1; fi
$(CXX) $(CFLAGS) $(INC) -o plugin.cpp.o -c plugin.cpp
$(CXX) $(CFLAGS) $(INC) -o LogicalFile1.cpp.o -c File1/LogicalFile1.cpp
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile1.cpp.o -c File1/PhysicalFile1.cpp
$(CXX) $(CFLAGS) $(INC) -o LogicalFile2.cpp.o -c File2/LogicalFile2.cpp
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile2.cpp.o -c File2/PhysicalFile2.cpp
### etc.
$(CXX) $(CFLAGS) $(INC) -o libname.so \
plugin.cpp.o \
LogicalFile1.cpp.o \
PhysicalFile1.cpp.o \
LogicalFile2.cpp.o \
PhysicalFile2.cpp.o \
### etc \
$(LIBS)
clean:
rm -f *.o *.so
The biggest issue I have is that there is only one rule (all), and I cannot find an example of a Makefile that does this or how to split it into multiple rules.
In this case, it's actually pretty straightforward. Right now, you just have an all target that's doing all the building. You need to break out the compiler invocations and link step into their own rules, and you should be off to the races:
BOOST_LOCATION=/usr/local/boost_1_54_0
CFLAGS=-pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -D__STDC_FORMAT_MACROS -Wno-system-headers -isystem -O2 -g -DNDEBUG -ggdb3 -D__STDC_LIMIT_MACROS
INC=-I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
LIBS=-L"$(IN_SOURCE_DIR)/lib" -shared -Wl,-soname,libname.so -L. -lm
all: plugin.cpp.o LogicalFile1.cpp.o PhysicalFile1.cpp.o LogicalFile2.cpp.o PhysicalFile2.cpp.o
$(CXX) $(CFLAGS) $(INC) -o libname.so \
plugin.cpp.o \
LogicalFile1.cpp.o \
PhysicalFile1.cpp.o \
LogicalFile2.cpp.o \
PhysicalFile2.cpp.o \
### etc \
$(LIBS)
plugin.cpp.o: plugin.cpp | test
$(CXX) $(CFLAGS) $(INC) -o plugin.cpp.o -c plugin.cpp
LogicalFile1.cpp.o: File1/LogicalFile1.cpp | test
$(CXX) $(CFLAGS) $(INC) -o LogicalFile1.cpp.o -c File1/LogicalFile1.cpp
PhysicalFile1.cpp.o: File1/PhysicalFile1.cpp | test
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile1.cpp.o -c File1/PhysicalFile1.cpp
LogicalFile2.cpp.o: File2/LogicalFile2.cpp | test
$(CXX) $(CFLAGS) $(INC) -o LogicalFile2.cpp.o -c File2/LogicalFile2.cpp
PhysicalFile2.cpp.o: File2/PhysicalFile2.cpp | test
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile2.cpp.o -c File2/PhysicalFile2.cpp
test:
#if test ! -d "$(IN_SOURCE_DIR)"; then echo "Error. Try:\n\nmake IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>"; exit 1; fi
clean:
rm -f *.o *.so
.PHONY: all clean test
From this point, you can simplify further, too. You could consolidate all of the compile lines into a single pattern rule, for example.
If you're willing to use the standard formats and built-in rules for make, you can write your entire makefile as easily as this:
ifeq (,$(wildcard $(IN_SOURCE_DIR)/.))
$(error Try: make IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>)
endif
OBJECTS = plugin.o LogicalFile1.o PhysicalFile1.o LogicalFile2.o PhysicalFile2.o ### etc
BOOST_LOCATION = /usr/local/boost_1_54_0
CPPFLAGS = -DNDEBUG -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
CXXFLAGS = -pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -Wno-system-headers -isystem -O2 -g -ggdb3
LDFLAGS = -L"$(IN_SOURCE_DIR)/lib" -L.
LDLIBS = -shared -Wl,-soname,libname.so -lm
all: libname.so
libname.so: $(OBJECTS)
$(LINK.cc) $^ $(LDLIBS) -o $#
clean:
rm -f *.o *.so
.PHONY: all clean

howto compile cryptopp 5.6.2 with mingw

I am trying to build cryptopp 5.6.1 with mingw 4.8.1 (sjlj). I've changed GNUMakefile from Crypto++ & MinGW
But there are several issue:
I've compile error if I try to build it as shared library;
On my machine it works (intel i5 (2nd generation) with Windows 7 ) but on Windows Xp on an Intel atom D2500 an error occured (no entry point for memmove_s in msvcrt.dll )
When I try to build as shared library I've the following error:
make dll
make: *** No rule to make target 'cryptopp.dll', needed by 'cryptest.import.exe'. Stop.
make libcryptopp.dll
// ...
g++ -std=c++11 -DNDEBUG -O3 -m32 -msse2 -msse3 -mssse3 -DCRYPTOPP_EXPORTS -c hex.cpp -o hex.export.o
g++ -std=c++11 -DNDEBUG -O3 -m32 -msse2 -msse3 -mssse3 -DCRYPTOPP_EXPORTS -c hmac.cpp -o hmac.export.o
g++ -std=c++11 -DNDEBUG -O3 -m32 -msse2 -msse3 -mssse3 -DCRYPTOPP_EXPORTS -c integer.cpp -o integer.export.o
g++ -std=c++11 -DNDEBUG -O3 -m32 -msse2 -msse3 -mssse3 -DCRYPTOPP_EXPORTS -c iterhash.cpp -o iterhash.export.o
g++ -std=c++11 -DNDEBUG -O3 -m32 -msse2 -msse3 -mssse3 -DCRYPTOPP_EXPORTS -c misc.cpp -o misc.export.o
g++ -std=c++11 -DNDEBUG -O3 -m32 -msse2 -msse3 -mssse3 -DCRYPTOPP_EXPORTS -c modes.cpp -o modes.export.o
make: *** No rule to make target 'modexppc.export.o', needed by 'libcryptopp.dll'. Stop.
Does someone has compiled succeful crypto++ with mingw 4.8.1? This is the snippet of my makefile:
CXXFLAGS = -std=c++11 -DNDEBUG -O3 -m32 -msse2 -msse3 -mssse3
ARFLAGS = rc
LDLIBS += -lws2_32
LDFLAGS =
MKDIR = mkdir
CP = copy
SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
# test.o needs to be after bench.o for cygwin 1.1.4 (possible ld bug?)
TESTOBJS = bench.o bench2.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o fipsalgt.o dlltest.o
LIBOBJS = $(filter-out $(TESTOBJS),$(OBJS))
DLLSRCS = algebra.cpp algparam.cpp asn.cpp basecode.cpp cbcmac.cpp channels.cpp cryptlib.cpp des.cpp dessp.cpp dh.cpp dll.cpp dsa.cpp ec2n.cpp eccrypto.cpp ecp.cpp eprecomp.cpp files.cpp filters.cpp fips140.cpp fipstest.cpp gf2n.cpp gfpcrypt.cpp hex.cpp hmac.cpp integer.cpp iterhash.cpp misc.cpp modes.cpp modexppc.cpp mqueue.cpp nbtheory.cpp oaep.cpp osrng.cpp pch.cpp pkcspad.cpp pubkey.cpp queue.cpp randpool.cpp rdtables.cpp rijndael.cpp rng.cpp rsa.cpp sha.cpp simple.cpp skipjack.cpp strciphr.cpp trdlocal.cpp
DLLOBJS = $(DLLSRCS:.cpp=.export.o)
LIBIMPORTOBJS = $(LIBOBJS:.o=.import.o)
TESTIMPORTOBJS = $(TESTOBJS:.o=.import.o)
DLLTESTOBJS = dlltest.dllonly.o
lib: libcryptopp.a
all: cryptest.exe
test: cryptest.exe
cryptest.exe v
install: lib
$(CP) *.h include\cryptopp
$(CP) *.a lib
clean:
del cryptest.exe libcryptopp.a $(LIBOBJS) $(TESTOBJS) cryptopp.dll libcryptopp.dll.a libcryptopp.import.a cryptest.import.exe dlltest.exe $(DLLOBJS) $(LIBIMPORTOBJS) $(TESTIMPORTOBJS) $(DLLTESTOBJS)
libcryptopp.a: $(LIBOBJS)
$(AR) $(ARFLAGS) $# $(LIBOBJS)
libcryptopp.so: $(LIBOBJS)
$(CXX) -shared -o $# $(LIBOBJS)
cryptest.exe: libcryptopp.a $(TESTOBJS)
$(CXX) -o $# $(CXXFLAGS) $(TESTOBJS) -L. -lcryptopp $(LDFLAGS) $(LDLIBS)
nolib: $(OBJS) # makes it faster to test changes
$(CXX) -o ct $(CXXFLAGS) $(OBJS) $(LDFLAGS) $(LDLIBS)
dll: cryptest.import.exe dlltest.exe
libcryptopp.dll: $(DLLOBJS)
$(CXX) -shared -o $# $(CXXFLAGS) $(DLLOBJS) $(LDFLAGS) $(LDLIBS) -Wl,--out-implib=libcryptopp.dll.a
libcryptopp.import.a: $(LIBIMPORTOBJS)
$(AR) $(ARFLAGS) $# $(LIBIMPORTOBJS)
$(RANLIB) $#
cryptest.import.exe: cryptopp.dll libcryptopp.import.a $(TESTIMPORTOBJS)
$(CXX) -o $# $(CXXFLAGS) $(TESTIMPORTOBJS) -L. -lcryptopp.dll -lcryptopp.import $(LDFLAGS) $(LDLIBS)
dlltest.exe: cryptopp.dll $(DLLTESTOBJS)
$(CXX) -o $# $(CXXFLAGS) $(DLLTESTOBJS) -L. -lcryptopp.dll $(LDFLAGS) $(LDLIBS)
%.dllonly.o : %.cpp
$(CXX) $(CXXFLAGS) -DCRYPTOPP_DLL_ONLY -c $< -o $#
%.import.o : %.cpp
$(CXX) $(CXXFLAGS) -DCRYPTOPP_IMPORTS -c $< -o $#
%.export.o : %.cpp
$(CXX) $(CXXFLAGS) -DCRYPTOPP_EXPORTS -c $< -o $#
%.o : %.cpp
$(CXX) $(CXXFLAGS) -c $<
Edit
To let it work I've forced the funcion memmove_s defined in misc.h (of cryptopp) to be defined inlined and now works also on windows xp (where memmove_s is not defined in msvcrt.dll).
Question: Can I change the mscvrt.dll of windows xp with one defined on Windows 7?
A way to build it is using qmake:
I removed GNUMakefile,
qmake -project
I open the pro file into QtCreator, changed TEMPLATE to lib and added ws2_32 to lib
The pro file now looks something this
TEMPLATE = lib
INCLUDEPATH += .
CONFIG -= qt
HEADERS += ...
SOURCES += ...
win32-g++ {
QMAKE_CXXFLAGS += -msse -msse2 -msse3 -mssse3
LIBS += -lws2_32
}
It seems work.
it's a try
put modexppc.cpp to your CRYPTOPP folder.
modexppc.cpp
// modexppc.cpp - written and placed in the public domain by Wei Dai
#include "pch.h"
#ifndef CRYPTOPP_IMPORTS
#include "modexppc.h"
#include "asn.h"
NAMESPACE_BEGIN(CryptoPP)
NAMESPACE_END
#endif
I sent a patch fixing memmove_s in Windows XP to the MinGW developer team. It's been accepted and it will soon appear in the newer MinGW builds. By now it should be available on the CentOS 7 MinGW distribution and Fedora 21 MinGW.
Crypto++ 5.6.2 now builds fine without modification on MinGW, using make (and setting CC, CXX and PATH environment variables correctly). Tested on CentOS 7, which uses MinGW 4.9 IIRC.

makefile to compile multiple sources, with different flags

I have the following makefile:
CC = gcc
SRC = source1.c
EXE = source1
FLAGS = -fopenmp
all: $(src)
$(CC) -o $(EXE) $(SRC) $(FLAGS)
clean:
rm $(EXE)
How can I modify it so I can use multiple sources, some of them compiled with the flag -fopenmp, some of them compiled without. Thanks a lot.
This should get you started: Note how -fopenmp gets added just for source2.c
CC=gcc
SRC=source1.c source2.c
OBJ=$(patsubst %.c,%.o,$(SRC))
EXE=source1
FLAGS= -g -O2
source2.o: FLAGS+=-fopenmp
all: $(EXE)
$(EXE): $(OBJ)
$(CC) -o $# $^ $(FLAGS)
%.o: %.c
$(CC) -c -o $# $^ $(FLAGS)
clean:
rm $(EXE)$
Output of make -Bsn:
gcc -o source1.o source1.c -g -O2
gcc -o source2.o source2.c -g -O2 -fopenmp
gcc -o source1 source1.o source2.o -g -O2
You can define for example, EXTFLAGS=$(FLAGS) -fopenmp, and use EXTFLAGS for some rules.