I want to test a complex shared library (cxsc) with the help of cmake. After a lot of trial and error i managed to create a html coverage report but the lines I test, with the boost testing framework, are still red.
This is the script I use to create the coverage report:
rm -fr build_coverage
mkdir build_coverage
cd build_coverage
cmake \
-DCMAKE_BUILD_TYPE=Coverage \
..
make
cd ../tests
make clean
make
cd ../build_coverage
make cxsc_coverage
The cmake part where the coverage report gets created:
# Cleanup lcov
COMMAND ${LCOV_PATH} --zerocounters --directory ${CMAKE_CURRENT_SOURCE_DIR}/build_coverage/CMakeFiles/cxsc.dir/src
COMMAND ${LCOV_PATH} --capture --initial --no-external --directory ${CMAKE_CURRENT_SOURCE_DIR}/build_coverage/CMakeFiles/cxsc.dir/src --output-file ${_outputname}.before
# Run tests
COMMAND LD_LIBRARY_PATH=${CMAKE_CURRENT_SOURCE_DIR}/build_coverage ${_testrunner} ${ARGV3}
# Capturing lcov counters and generating report
COMMAND ${LCOV_PATH} --capture --no-checksum --no-external --directory ${CMAKE_CURRENT_SOURCE_DIR}/build_coverage/CMakeFiles/cxsc.dir/src --output-file ${_outputname}.after
COMMAND ${LCOV_PATH} --add-tracefile ${_outputname}.before --add-tracefile ${_outputname}.after --output-file ${_outputname}.info
COMMAND ${GENHTML_PATH} -o ${_outputname} ${_outputname}.info
Makefile of the test binary (I think this is where the error is):
g++ \
-o test_runner \
main.cpp \
test_interval.cpp \
-I./../src \
-I./../src/rts \
-I./../src/asm \
-I./../src/fi_lib \
-I./../build_coverage \
-L./../build_coverage \
-lcxsc \
-Wall -Winline \
-lboost_unit_test_framework
This is what happens:
cmake -DCMAKE_BUILD_TYPE=Coverage .. build_coverage directory is created with a target.dir directory and *.gcno files in it
cd tests && make Test executable is created and linked against the shared library in the build_coverage directory (Maybe here is my mistake)
make coverage Coverage data is collected and tests are executed
Edit:
To clarify my problem, there are some lines covered but only global consts or one helper function which is used pretty often. But not the functions/methods I call in my tests.
Files in build_coverage/CMakeFiles/cxsc.dir/src/:
After cmake -DC...: A few *.cmake and *.make files
After make in build_coverage dir: *.gcno files
After lcov -c -i ...: Still *.gcno files
After running tests: *.gcda and *.gcno files
After lcov -c ...: A lot of movement in the directory but still the same filenames
I don't see any gcov flags in your makefile. Try this one for test_runner :
g++ \
-Wall -Winline -fprofile-arcs -ftest-coverage \
main.cpp \
test_interval.cpp \
-I./../src \
-I./../src/rts \
-I./../src/asm \
-I./../src/fi_lib \
-I./../build_coverage \
-L./../build_coverage \
-lcxsc \
-lboost_unit_test_framework \
-lgcov \
-o test_runner
Your shared library need those flags too :
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov")
See this post with a similar problem.
NB : "--coverage" can substitute "-fprofile-arcs -ftest-coverage" and "-lgcov"
Related
I have the arm-none-linux-gnueabi-g++ compiler in the below path,
root#user-VirtualBox:~# which arm-none-linux-gnueabi-g++
/home/user/octane_etk-6.0.0.240/arm-toolchain/bin/arm-none-linux-gnueabi-g++
and I have given the same in DCMAKE_COMPILER path in the build command of paho,
user#user-VirtualBox:~/octane_etk_sample-6.0.0.240/paho.mqtt.c$ cmake -Bbuild -H. -DPAHO_WITH_SSL=OFF -DPAHO_ENABLE_TESTING=OFF -DCMAKE_C_COMPILER=/home/user/octane_etk-6.0.0.240/arm-toolchain/bin/arm-none-linux-gnueabi-gcc -DCMAKE_CXX_COMPILER=/home/user/octane_etk-6.0.0.240/arm-toolchain/bin/arm-none-linux-gnueabi-g++
-- The C compiler identification is GNU 4.8.1
-- Check for working C compiler: /home/user/octane_etk-6.0.0.240/arm-toolchain/bin/arm-none-linux-gnueabi-gcc
-- Check for working C compiler: /home/user/octane_etk-6.0.0.240/arm-toolchain/bin/arm-none-linux-gnueabi-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- CMake version: 3.10.2
-- CMake system name: Linux
-- Timestamp is 2020-04-17T07:33:49Z
-- Configuring done
-- Generating done
CMake Warning:
Manually-specified variables were not used by the project:
CMAKE_CXX_COMPILER
-- Build files have been written to: /home/user/octane_etk_sample-6.0.0.240/paho.mqtt.c/build
After this build I have given,
$ sudo cmake --build build/ --target install
$ sudo ldconfig
and I have copied libpaho-mqtt3c.so, libpaho-mqtt3c.so.1, libpaho-mqtt3c.so.1.3.1 from "/home/user/octane_etk_sample-6.0.0.240/paho.mqtt.c/build/src/" to the same folder where this "-lltkcpp_atmel" resides.
Whereas, when I give make it says, cannot find -lpaho-mqtt3c,
root#user-VirtualBox:/home/user/octane_etk_sample-6.0.0.240# make arm
mkdir -p ./bin
arm-none-linux-gnueabi-g++ \
-Wno-write-strings \
-Iinclude \
speedway_embedded_example.cpp -lpaho-mqtt3c \
-Llib \
-static -lltkcpp_atmel -lltkcppimpinj_atmel -lxml2_atmel \
-lssl_atmel -lcrypto_atmel -ldl_atmel \
-o bin/speedwayr_arm
/home/user/octane_etk-6.0.0.240/arm-toolchain/bin/../lib/gcc/arm-none-linux-gnueabi/4.8.1/../../../../arm-none-linux-gnueabi/bin/ld: cannot find -lpaho-mqtt3c
How to overcome this issue? Is it something wrong while building the paho against arm-none-linux-gnueabi-gcc & g++?
Note 1:
Compiler command suggested by David Ranieri
root#user-VirtualBox:/home/mindlogic/octane_etk_sample-6.0.0.240# make arm
mkdir -p ./bin
arm-none-linux-gnueabi-g++ \
-Wno-write-strings \
-o bin/speedwayr_arm \
-Iinclude \
speedway_embedded_example.cpp -lpaho-mqtt3c \
-Llib \
-static -lltkcpp_atmel -lltkcppimpinj_atmel -lxml2_atmel \
-lssl_atmel -lcrypto_atmel -ldl_atmel
/home/mindlogic/octane_etk-6.0.0.240/arm-toolchain/bin/../lib/gcc/arm-none-linux-gnueabi/4.8.1/../../../../arm-none-linux-gnueabi/bin/ld: cannot find -lpaho-mqtt3c
Note 2:
I have changed the cmake build from
cmake -Bbuild -H. -DPAHO_WITH_SSL=OFF -DPAHO_ENABLE_TESTING=OFF -DCMAKE_C_COMPILER=/home/user/octane_etk-6.0.0.240/arm-toolchain/bin/arm-none-linux-gnueabi-gcc -DCMAKE_CXX_COMPILER=/home/user/octane_etk-6.0.0.240/arm-toolchain/bin/arm-none-linux-gnueabi-g++
to
cmake -Bbuild -H. -DPAHO_WITH_SSL=OFF -DPAHO_ENABLE_TESTING=OFF
-DPAHO_BUILD_STATIC=True -DCMAKE_C_COMPILER=/home/user/octane_etk-6.0.0.240/arm-toolchain/bin/arm-none-linux-gnueabi-gcc -DCMAKE_CXX_COMPILER=/home/user/octane_etk-6.0.0.240/arm-toolchain
After building a library as static one, now I can able to compile with "makr arm", successfully i.e., commands given below
root#user-VirtualBox:/home/user/octane_etk_sample-6.0.0.240# make cap
mkdir -p ./bin
arm-none-linux-gnueabi-g++ \
-Wno-write-strings \
-Iinclude \
speedway_embedded_example.cpp \
-Llib \
-static -lltkcpp_atmel -lltkcppimpinj_atmel -lxml2_atmel \
-lssl_atmel -lcrypto_atmel -ldl_atmel -lpaho-mqtt3c-static -ljansson -lpthread \
-o bin/speedwayr_arm
Order matters, try generating the object before linking:
arm-none-linux-gnueabi-g++ \
-Wno-write-strings \
-o bin/speedwayr_arm \
-Iinclude \
speedway_embedded_example.cpp -lpaho-mqtt3c \
-Llib \
-static -lltkcpp_atmel -lltkcppimpinj_atmel -lxml2_atmel \
-lssl_atmel -lcrypto_atmel -ldl_atmel
Im trying to setup my home computer the same way as the computers at my school so I can work on my assignments from here, but I can't for the life of me get gtest working correctly. I've run through the recommended install process and figured out that it needs the ".so" libraries to not throw 'pthread' not found errors.
Makefile:
PROJECT_DIR = Electra
PROGRAM_TEST = testProject
CXX = g++
CXXFLAGS = -std=c++11 -g -fprofile-arcs -ftest-coverage
LINKFLAGS = -lgtest
SRC_DIR = src
TEST_DIR = test
SRC_INCLUDE = include
INCLUDE = -I ${SRC_INCLUDE}
GCOV = gcov
LCOV = lcov
COVERAGE_RESULTS = results.coverage
COVERAGE_DIR = docs/code/coverage
STATIC_ANALYSIS = cppcheck
STYLE_CHECK = cpplint.py
DOXY_DIR = docs/code
#Targets
#
#.PHONY: all
#all: $(PROGRAM_TEST) memcheck coverage docs static style
#Temporary all target. use ^^^ this one once docs and coverage required
.PHONY: all
all: $(PROGRAM_TEST) memcheck static style
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -rf *~ $(SRC)/*.o $(TEST_DIR)/output/*.dat \
*.gcov *.gcda *.gcno *.orig ???*/*.orig \
*.bak ???*/*.bak $(PROGRAM_GAME) \
???*/*~ ???*/???*/*~ $(COVERAGE_RESULTS) \
$(PROGRAM_TEST) $(MEMCHECK_RESULTS) $(COVERAGE_DIR) \
$(DOXY_DIR)/html obj bin
$(PROGRAM_TEST): $(TEST_DIR) $(SRC_DIR)
$(CXX) $(CXXFLAGS) -o $(PROGRAM_TEST) $(INCLUDE) \
$(TEST_DIR)/*.cpp $(SRC_DIR)/*.cpp $(LINKFLAGS)
tests: $(PROGRAM_TEST)
$(PROGRAM_TEST)
memcheck: $(PROGRAM_TEST)
valgrind --tool=memcheck --leak-check=yes $(PROGRAM_TEST)
fullmemcheck: $(PROGRAM_TEST)
valgrind --tool=memcheck --leak-check=full $(PROGRAM_TEST)
coverage: $(PROGRAM_TEST)
$(PROGRAM_TEST)
# Determine code coverage
$(LCOV) --capture --gcov-tool $(GCOV) --directory . --output-file $(COVERAGE_RESULTS)
# Only show code coverage for the source code files (not library files)
$(LCOV) --extract $(COVERAGE_RESULTS) */$(PROJECT_DIR)/$(SRC_DIR)/* -o $(COVERAGE_RESULTS)
#Generate the HTML reports
genhtml $(COVERAGE_RESULTS) --output-directory $(COVERAGE_DIR)
#Remove all of the generated files from gcov
rm -f *.gcda *.gcno
static: ${SRC_DIR} ${TEST_DIR}
${STATIC_ANALYSIS} --verbose --enable=all ${SRC_DIR} ${TEST_DIR} ${SRC_INCLUDE} --suppress=missingInclude
style: ${SRC_DIR} ${TEST_DIR} ${SRC_INCLUDE}
${STYLE_CHECK} $(SRC_INCLUDE)/* ${SRC_DIR}/* ${TEST_DIR}/*
#.PHONY: docs
#docs: ${SRC_INCLUDE}
# doxygen $(DOXY_DIR)/doxyfile
Running "make tests" results in the following
g++ -std=c++11 -g -fprofile-arcs -ftest-coverage -o testProject -I include \
test/*.cpp src/*.cpp -lgtest
testProject
make: testProject: Command not found
Makefile:53: recipe for target 'tests' failed
make: *** [tests] Error 127
Any idea as to why this wont work? Or how to even get started trying to resolve this? Its not a very detailed error. I don't want to change the Makefile, as it works for my school systems and this is a shared project.
My home system is running Windows 10, and im using the Ubuntu shell to run makefiles
In POSIX shells the current working directory is not searched by default. This is a safety measure that comes from POSIX's origins as a multi-user system: you don't want someone to be able to drop a program like ls in some directory and have unsuspecting people run it just by typing ls in that directory.
Apparently in your school systems, someone has added the current working directory (.) to your PATH environment variable, while at home you do not have it added.
Your makefile is wrong, the recipe should be:
tests: $(PROGRAM_TEST)
./$(PROGRAM_TEST)
to force the program from the current working directory to be run, instead of relying on the cwd appearing in the PATH (or running some other instance of testProgram that does happen to be on your PATH).
This will work on all your systems.
In Makefile.am, I have:
lib_LTLIBRARIES = libmyproject.la
libmyproject_la_LDFLAGS = -shared
libmyproject_la_SOURCES = \
sample1.cpp \
sample1.h \
sample2.cpp \
sample2.h
AM_CPPFLAGS = \
-Wall \
-Wextra
INCLUDES = \
$(OPENSSL_CFLAGS)
LIBS = \
-L/usr/lib/openssl-1.0.0/ \
-lssl
EXTRA_DIST = xxxxxx
This works fine and I'm getting .lo and .o files in the same path.
What can I do to have all .lo and .o files moved to a separate subfolder after compilation?
You could try a VPATH build. Having some insight as to why the .lo and .o files need to be elsewhere would help answer your question.
A somewhat different variation on this is the DESTDIR install where the libs, etc. get copied and the .o files don't.
For one thing you can mix in ordinary make rules into your Makefile.am.
So adding the following to Makefile.am should do what you want:
.PHONY: copy_obj
# when building 'all', we *also* want the 'copy_obj' target
all: copy_obj
# but the 'copy_obj' target can only be executed once 'libmyproject.la' is done
copy_obj: libmyproject.la
mkdir -p objdir
cp *.lo *.o objdir
or even:
.PHONY: copy_obj
all: copy_obj
copy_obj: $(libmyproject_la_OBJECT)
mkdir -p objdir
cp $^ objdir
But the real question is: why would you actually want to do that? What do you try to accomplish?
I have a script which generates multiple C++ .h and .cpp files, based on a configuration file. This script also generates a file called 'Makefile.inc', and this file contains a variable with the required object filenames, for the generated .cpp files.
Example of a Makefile.inc file (all paths are absolute):
MESSAGE_OBJS = \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/error-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/challenge-request-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/challenge-response-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/login-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/get-game-list-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/game-list-response-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/join-game-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/connect-to-game-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/leave-game-message.o
Using the answer in this question as base, I created the following Makefile:
# Include the generated makefile for messages.
# This includes a variable with all message targets
include atlarge/messages/Makefile.inc
# Create a variable with all source targets
LIBOBJS = \
atlarge/exceptions.o \
atlarge/message-factory.o \
atlarge/envelope.o \
atlarge/client.o \
atlarge/user.o \
atlarge/atlarge-protocol.o \
atlarge/atlarge-gameserver.o \
$(MESSAGE_OBJS)
CXXFLAGS += -W -Wall -I. -g -O3 -MD \
`pkg-config jansson --cflags` \
`libgcrypt-config --cflags` \
`pkg-config glib-2.0 --cflags` \
-fPIC -DDEBUG -DENABLE_LOGGING
PREFIX = /usr/local
# TODO use pkg-config for jansson
LDLIBS += -lm -ljansson -latlarge-util `libgcrypt-config --libs` `pkg-config glib-2.0 --libs`
LDFLAGS += -shared -L/usr/local/lib
# Include automatically generated dependencies
-include $(LIBOBJS:.o=.d)
all: libatlarge.so
# If the message Makefile doesn't exist yet, generate it
atlarge/messages/Makefile.inc: atlarge/messages/messages.conf
python ../common/messagegen.py -o ./atlarge/messages/ atlarge/messages/messages.conf
libatlarge.so: $(LIBOBJS)
$(CXX) $(LDFLAGS) -o $# $^ $(LDLIBS)
clean:
#rm -f *.o
#rm -f atlarge/*.o
#rm -f atlarge/messages/*.o
#rm -f atlarge/messages/*.cpp
#rm -f atlarge/messages/*.h
#rm -f atlarge/messages/Makefile.inc
#rm -f atlarge/*.d
#rm -f atlarge/messages/*.d
#rm -f *.d
#rm -f ../common/*.d
#rm -f ../common/*.o
#rm -f *.a
#rm -f *.so
#rm -f tags
install: libatlarge.so
#install -m 0644 $^ $(PREFIX)/lib
#install -m 0755 -d $(PREFIX)/include/atlarge
#install -m 0755 -d $(PREFIX)/include/atlarge/messages
#install -m 0644 -D atlarge/*.h $(PREFIX)/include/atlarge
#install -m 0644 -D atlarge/messages/*.h $(PREFIX)/include/atlarge/messages
#ldconfig
#echo "Installed"
.PHONY: all clean install splint messages
As you can see, I first include the generated Makefile.inc. Then a variable with all library object files is defined, and this variable makes use of the variable declared in the generated Makefile.inc. After that some variables with compiler flags are declared.
To make use of Makefile remaking, I included a target rule for the generated Makefile.inc, so if the dependency of Makefile.inc (the configuration file) is newer than Makefile.inc, it gets regenerated, and Make will restart itself.
So this is the goal:
Check if Makefile.inc needs to be (re)generated.
Include it
Use the variable inside Makefile.inc in the $LIBOBJS variable in the main Makefile.
And this actually works. If I update the messages.conf file, Make detects that, and will run the python script. It will then restart itself, include the new Makefile.inc, and then proceed with compiling.
But here comes the part that doesn't work: if I don't update the messages.conf file, but only .h or .cpp files which are by default in the $LIBOBJS list, Make will not proceed to compile.
For example, if alter client.cpp and no other files, I get the following error:
make: `atlarge/exceptions.o' is up to date.
Well yeah, great you found out that exceptions.o is up to date, but I altered client.cpp, so why don't you start compiling that one? Why does make quit immediatly after seeing that the first target in LIBOBJS is up to date?
Who knows what's causing this, and what could be a solution? Is there maybe a better way to handle code generation with makefiles?
Thanks in advance.
NB: I also use dependency files generated by gcc, and that was working fine before I added the code generation, so I don't think that's a problem.
You need to move the all target to come BEFORE the include. Make always builds the first target it sees in the makefile unless you give a specific target on the command line. Since the include comes before any target, the first target defined in Makefile.inc will be the default target and when you run make that's the one that will be built. That's why it tries to build exceptions.o and then stops. If you run make all explicitly, it will work as you expect.
Where is the dependency for the object files on the source files
or the header files? There is an implicit rule which should
pick up the dependencies if the .cpp file is in the same
directory as the .o, but if they're not, you'll have to
provide your own, or use VPATH (see §4.5.1 in the manual). And
you also need to generate the dependencies for the includes, see
§4.1.4 in the manual.
I've got a Stellaris Launchpad board with a Cortex M4F on it. I want to use FreeRTOS on the board with some of my own C++ code. FreeRTOS, however, is written in C so will not compile with G++; I've tried.
I read somewhere that I should compile FreeRTOS with gcc, then compile my application code with g++, then pull them together using the linker. This makes sense, but I'm really struggling with how to put this behaviour down in a Makefile. I found this Makefile which just confused me more.
Currently, I'm just using the Makefile distributed with the FreeRTOS example in the Stellaris demos, but that's set up for C code only. This question is asking something similar to what I'm after, but I can't wrap my head around how to compile FreeRTOS with GCC and the rest of my code with G++.
FreeRTOS apparently wraps it's code in extern "C" { } directives but attempting using G++ still fails when compiling the FreeRTOS codebase.
I don't like posting large amounts of code on SO, but the more information the better I suppose. The Stellaris demos have a common makedefs file:
# Get the operating system name. If this is Cygwin, the .d files will be
# munged to convert c: into /cygdrive/c so that "make" will be happy with the
# auto-generated dependencies.
os:=${shell uname -s}
# The compiler to be used.
ifndef COMPILER
COMPILER=gcc
endif
# Definitions for using GCC.
ifeq (${COMPILER}, g++)
# Get the prefix for the tools to use. Use arm-stellaris-eabi if it exists,
# otherwise fall back to arm-none-eabi.
PREFIX=${shell type arm-stellaris-eabi-gcc > /dev/null 2>&1 && \
echo arm-stellaris-eabi || echo arm-none-eabi}
# The command for calling the compiler.
CC=${PREFIX}-${COMPILER}
# The location of the C compiler
# ARMGCC_ROOT is used by some makefiles that need to know where the compiler
# is installed. It is not used further for normal stellarisware apps
ARMGCC_ROOT:=${shell dirname '${shell sh -c "which ${CC}"}'}/..
# Determine the compiler CPU/FPU options based on the processor variant.
ifndef VARIANT
CPU=-mcpu=cortex-m3
FPU=
else
ifeq (${VARIANT}, cm3)
CPU=-mcpu=cortex-m3
FPU=
else
ifeq (${VARIANT}, cm4f)
CPU=-mcpu=cortex-m4
FPU=-mfpu=fpv4-sp-d16 -mfloat-abi=softfp
else
$(error Unknown processor variant ${VARIANT}!)
endif
endif
endif
# The flags passed to the assembler.
AFLAGS=-mthumb \
${CPU} \
${FPU} \
-MD
# The flags passed to the compiler.
CFLAGS=-mthumb \
${CPU} \
${FPU} \
-Os \
-ffunction-sections \
-fdata-sections \
-MD \
-Wall \
-pedantic \
-DPART_${PART} \
-c
# The command for calling the library archiver.
AR=${PREFIX}-ar
# The command for calling the linker.
LD=${PREFIX}-ld
# The flags passed to the linker.
LDFLAGS=--gc-sections
# Get the location of libgcc.a from the GCC front-end.
LIBGCC=${shell ${CC} ${CFLAGS} -print-libgcc-file-name}
# Get the location of libc.a from the GCC front-end.
LIBC=${shell ${CC} ${CFLAGS} -print-file-name=libc.a}
# Get the location of libm.a from the GCC front-end.
LIBM=${shell ${CC} ${CFLAGS} -print-file-name=libm.a}
# The command for extracting images from the linked executables.
OBJCOPY=${PREFIX}-objcopy
# Tell the compiler to include debugging information if the DEBUG environment
# variable is set.
ifdef DEBUG
CFLAGS+=-g -D DEBUG
endif
# Add the tool specific CFLAGS.
CFLAGS+=${CFLAGSgcc}
# Add the include file paths to AFLAGS and CFLAGS.
AFLAGS+=${patsubst %,-I%,${subst :, ,${IPATH}}}
CFLAGS+=${patsubst %,-I%,${subst :, ,${IPATH}}}
# The rule for building the object file from each C source file.
${COMPILER}${SUFFIX}/%.o: %.c
#if [ 'x${VERBOSE}' = x ]; \
then \
echo " CC ${<}"; \
else \
echo ${CC} ${CFLAGS} -D${COMPILER} -o ${#} ${<}; \
fi
#${CC} ${CFLAGS} -D${COMPILER} -o ${#} ${<}
ifneq ($(findstring CYGWIN, ${os}), )
#sed -i -r 's/ ([A-Za-z]):/ \/cygdrive\/\1/g' ${#:.o=.d}
endif
# The rule for building the object file from each assembly source file.
${COMPILER}${SUFFIX}/%.o: %.S
#if [ 'x${VERBOSE}' = x ]; \
then \
echo " AS ${<}"; \
else \
echo ${CC} ${AFLAGS} -D${COMPILER} -o ${#} -c ${<}; \
fi
#${CC} ${AFLAGS} -D${COMPILER} -o ${#} -c ${<}
ifneq ($(findstring CYGWIN, ${os}), )
#sed -i -r 's/ ([A-Za-z]):/ \/cygdrive\/\1/g' ${#:.o=.d}
endif
# The rule for creating an object library.
${COMPILER}${SUFFIX}/%.a:
#if [ 'x${VERBOSE}' = x ]; \
then \
echo " AR ${#}"; \
else \
echo ${AR} -cr ${#} ${^}; \
fi
#${AR} -cr ${#} ${^}
# The rule for linking the application.
${COMPILER}${SUFFIX}/%.axf:
#if [ 'x${SCATTERgcc_${notdir ${#:.axf=}}}' = x ]; \
then \
ldname="${ROOT}/${COMPILER}/standalone.ld"; \
else \
ldname="${SCATTERgcc_${notdir ${#:.axf=}}}"; \
fi; \
if [ 'x${VERBOSE}' = x ]; \
then \
echo " LD ${#} ${LNK_SCP}"; \
else \
echo ${LD} -T $${ldname} \
--entry ${ENTRY_${notdir ${#:.axf=}}} \
${LDFLAGSgcc_${notdir ${#:.axf=}}} \
${LDFLAGS} -o ${#} $(filter %.o %.a, ${^}) \
'${LIBM}' '${LIBC}' '${LIBGCC}'; \
fi; \
${LD} -T $${ldname} \
--entry ${ENTRY_${notdir ${#:.axf=}}} \
${LDFLAGSgcc_${notdir ${#:.axf=}}} \
${LDFLAGS} -o ${#} $(filter %.o %.a, ${^}) \
'${LIBM}' '${LIBC}' '${LIBGCC}'
#${OBJCOPY} -O binary ${#} ${#:.axf=.bin}
endif
The above file is included by the Makefile itself (below):
# Defines the part type that this project uses.
PART=LM4F120H5QR
# Set the processor variant.
VARIANT=cm4f
# The base directory for StellarisWare.
ROOT=../lib
COMPILER=gcc
# Include the common make definitions.
include ${ROOT}/makedefs
# Where to find source files that do not live in this directory.
VPATH=${ROOT}/FreeRTOS/Source/portable/GCC/ARM_CM4F
VPATH+=${ROOT}/FreeRTOS/Source/portable/MemMang/
VPATH+=${ROOT}/FreeRTOS/Source
VPATH+=${ROOT}/drivers
VPATH+=${ROOT}/utils
# Where to find header files that do not live in the source directory.
IPATH=.
IPATH+=..
IPATH+=${ROOT}
IPATH+=${ROOT}/FreeRTOS/Source/portable/GCC/ARM_CM4F
IPATH+=${ROOT}/FreeRTOS
IPATH+=${ROOT}/FreeRTOS/Source/include
IPATH+=${ROOT}
# The default rule, which causes the FreeRTOS example to be built.
all: ${COMPILER}
all: ${COMPILER}/freertos_demo.axf
# The rule to clean out all the build products.
clean:
#rm -rf ${COMPILER} ${wildcard *~}
# The rule to create the target directory.
${COMPILER}:
#mkdir -p ${COMPILER}
# Rules for building the FreeRTOS example.
${COMPILER}/freertos_demo.axf: ${COMPILER}/buttons.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/freertos_demo.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/heap_2.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/led_task.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/list.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/port.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/queue.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/rgb.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/startup_${COMPILER}.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/switch_task.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/tasks.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/uartstdio.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/ustdlib.o
${COMPILER}/freertos_demo.axf: ${ROOT}/driverlib/${COMPILER}-cm4f/libdriver-cm4f.a
${COMPILER}/freertos_demo.axf: freertos_demo.ld
SCATTERgcc_freertos_demo=freertos_demo.ld
ENTRY_freertos_demo=ResetISR
CFLAGSgcc=-DTARGET_IS_BLIZZARD_RA1
# Include the automatically generated dependency files.
ifneq (${MAKECMDGOALS},clean)
-include ${wildcard ${COMPILER}/*.d} __dummy__
endif
Some of my directory structure is as follows:
Projects/
lib/
FreeRTOS/
driverlib/
drivers/
inc/
utils/
makedefs
TestProject/
loads.cpp
of.cpp
files.h
here.h
Makefile
If I'm correct in saying that FreeRTOS must be compiled with GCC, then linked with my C++ project code, how can I modify my current Makefile to do that? I want a reasonably generic solution so I can re-use it in other projects, but I don't know much about the C/C++ build process or Makefiles, hence me asking this (lengthy) question. I don't want/mean to sound like I'm asking a "do this for me" question, but I really cannot work out how to do this despite searching on Google and on SO.
I don't use FreeRTOS with C++ myself, but it has been discussed many times on the FreeRTOS forum and there are a few C++ frameworks in the FreeRTOS Interactive site.