STM32F4-Discovery linking issue - linker

I am trying to get some code up and running on a STM32F4-Discovery board (chip: STM32F407VGT6).
This tutorial explains the necessary code and steps required for compiling and linking for the Nucleo board (chip: STM32F401RE). I have tried to convert this procedure to my Discovery board but I get the following linking errors when I try to link the object files
error: system.o: Conflicting architecture profiles M/A
failed to merge target specific data of file system.o
error: main.o: Conflicting architecture profiles M/A
failed to merge target specific data of file main.o
error: startup_stm32f407xx.o: Conflicting architecture profiles M/A
failed to merge target specific data of file startup_stm32f407xx.o
My project structure is the following
├── STM32Cube_FW_F4_V1.13.0
│   ├── Drivers/
│   ├── Projects/
│   └── Utilities/
├── stm32f4 (my project folder)
│   ├── main.c
│   ├── Makefile
│   ├── startup_stm32f407xx.s
│   └── system.c
This is my Makefile (STM32CubeF4 can be found here):
STM32Cube:=../STM32Cube_FW_F4_V1.13.0
#DEVICE:=STM32F07xG
DEVICE:=STM32F407xx
CC:=arm-none-eabi
CFLAGS:=-Wall -mcpu=cortex-m4 -mlittle-endian -mthumb
INC_PATH1:=$(STM32Cube)/Drivers/CMSIS/Device/ST/STM32F4xx/Include
INC_PATH2:=$(STM32Cube)/Drivers/CMSIS/Include
LD_SCRIPT:=$(STM32Cube)/Projects/STM32F4-Discovery/Templates/TrueSTUDIO/STM32F4-Discovery/STM32F407VG_FLASH.ld
all:
$(CC)-gcc $(CFLAGS) -I$(INC_PATH1) -I$(INC_PATH2) -D$(DEVICE) -Os -c system.c -o system.o
$(CC)-gcc $(CFLAGS) -I$(INC_PATH1) -I$(INC_PATH2) -D$(DEVICE) -Os -c main.c -o main.o
$(CC)-gcc $(CFLAGS) -I$(INC_PATH1) -I$(INC_PATH2) -D$(DEVICE) -Os -c startup_stm32f407xx.s -o startup_stm32f407xx.o
link: all
$(CC)-gcc $(CFLAGS) -D$(DEVICE) -T$(LD_SCRIPT) -Wl,--gc-sections system.o main.o startup_stm32f407xx.o -o main.elf
I copied startup_stm32f407xx.o from
$(STM32Cube)/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc/startup_stm32f407xx.s
I have changed BSRRL and BSSRH to BSRR in main.c
and PWR_CR_VOS_1 to PWR_CR_VOS in system.c.
This changes were made so that the code would compile and the default variable names were absent in the headerfiles for my board.
I have looked over the tutorial twice and searched for information regarding the error message without being able to solve this issue.
Could someone tell me what I am doing wrong or point me in he right direction?

Related

Compiling multiple executable files with a static pattern rule in Makefile

I am writing a matrix library in C for practice. To enforce good habits I am testing using the Unity Testing Framework, meaning I compile multiple test files and run them. Since I do not know how many test files I will end up with, I've been trying to write my Makefile such that any .c file in my tests/ directory will be found and used to make a corresponding executable.
Here is my project file structure:
├── bin
├── include
| ├── fml.h
├── src
| ├── fml.c
├── test-framework
| ├── unity.c
| ├── unity.h
| ├── unity_internals.h
├── tests
| ├── check_fml_at.c
| ├── check_fml_set_at.c
| ├── check_fml_mem_management.c
├── Makefile
├── Readme
And here is the Makefile I'm struggling with:
BIN_DIR = bin
SRC_DIR = src
TESTS_DIR = tests
FML = $(BIN_DIR)/fml.o
TEST_FRAMEWORK = $(BIN_DIR)/unity.o
CFLAGS = -Wall -Werror -g
CC = gcc
TESTS = $(patsubst %.c, %, $(patsubst $(TESTS_DIR)/%, \
$(BIN_DIR)/%, $(wildcard $(TESTS_DIR)/*.c)))
$(info $$var is [${TESTS}])
$(TESTS): $(BIN_DIR)/%: $(TESTS_DIR)/%.c $(FML) $(TEST_FRAMEWORK)
$(CC) $(CFLAGS) $^ -o $# -Iinclude -Itest-framework
$(FML): src/fml.c include/fml.h
$(CC) $(CFLAGS) -c $< -o $# -Iinclude
$(TEST_FRAMEWORK): test-framework/unity.c test-framework/unity.h test-framework/unity_internals.h
$(CC) $(CFLAGS) -c $< -o $#
memcheck:
valgrind $(TESTS)
check:
$(TESTS)
clean:
rm $(TESTS) $(OBJS)
Each test file needs the library (fml) and the test framework (unity).
The expected behavior when running make is for check_fml_at, check_fml_set_at, and check_fml_mem_management to appear as executables in the bin/ file, along with fml.o and unity.o libraries. I've checked and the TESTS variable correctly evaluates to check_fml_at, check_fml_set_at, and check_fml_mem_management. But for some reason, only the first test is built, and when I run make I only see check_fml_at along with fml.o and unity.o in the bin dir.
Why is the makefile behaving this way? And what can I do to ensure every file in TESTS is built so I can run every test?
Thank you for any help!
-- Tomas Dougan
There does not appear to be anything inherently wrong with your static pattern rule. The reason that you are getting only one test built when you run make without arguments is that make then chooses a default target, not a default rule. If the first rule in the makefile has multiple targets then the one that appears first is the default target.
If you want the default to be to build all the tests, then insert a new first rule that specifies all the tests as prerequisites:
.PHONY: all
all: $(TESTS)
Do note, by the way, that your memcheck and check recipes aren't going to work as you appear to intend when more than one test is designated by $(TESTS). Instead of running each test, you will run just the first, with the names of the others passed as command-line arguments. Perhaps you want something more like
.PHONY: memcheck check
memcheck:
for t in $(TESTS); do valgrind $$t; done
check:
for t in $(TESTS); do $$t; done

differences between linux and windows makefile?

Already build a C program in Windows environment and make this makefile
# project name (generate executable with this name)
TARGET = Orga_L1_MATURANA
CC = gcc
# compiling flags here
CFLAGS = -Wall -I.
LINKER = gcc
# linking flags here
LFLAGS = -Wall -I. -lm
# change these to proper directories where each file should be
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SOURCES := $(wildcard $(SRCDIR)/main.c)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm = rm -f
$(BINDIR)/$(TARGET): $(OBJECTS)
#$(LINKER) $(OBJECTS) $(LFLAGS) -o $#
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) -c $< -o $#
#echo "Compiled "$<" successfully!"
and this tree's see of the code
.
├── bin
│   ├── lineasControl2.txt
│   ├── mipsEjemplo2.asm
│   └── Orga_L1_MATURANA
├── makefile
├── obj
│   └── main.o
├── README.md
└── src
├── 2EnlazadasCursor.c
├── cons.c
├── cons.h
├── funciones.c
├── funciones.h
├── main.c
├── operaciones.c
└── structs.h
its fine the way that im doing the makefile for both OS? Besides, i hear that ubuntu doesnt needs a makefile, is that right? I dont think so.

How can I use the check testing framework from Clion and Cmake?

I use the check testing framework to unit test my C code. The test when it's run looks like this.
$ checkmk tst_bquotes.check > bquotes-test.c
dac#dac-Latitude-E7450:~/kth/os/lab3/openshell$ gcc -Wall -o bquotes-test util.c errors.c bquotes-test.c -lcheck -lsubunit -lrt -pthread -lm
dac#dac-Latitude-E7450:~/kth/os/lab3/openshell$ ./bquotes-test
Running suite(s): Core
100%: Checks: 1, Failures: 0, Errors: 0
How can I add this test to my cmake build script?
cmake_minimum_required(VERSION 3.0)
project(shell.test)
if (EDITLINE_LIBRARIES AND EDITLINE_INCLUDE_DIRS)
set(Editline_FIND_QUIETLY TRUE)
endif (EDITLINE_LIBRARIES AND EDITLINE_INCLUDE_DIRS)
find_path(EDITLINE_INCLUDE_DIRS NAMES editline/readline.h)
find_library(EDITLINE_LIBRARIES NAMES edit)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Editline DEFAULT_MSG
EDITLINE_LIBRARIES
EDITLINE_INCLUDE_DIRS)
mark_as_advanced(EDITLINE_INCLUDE_DIRS EDITLINE_LIBRARIES)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L/usr/local/include/ -L/usr/include -std=gnu99 -pedantic-errors -O3 -g -Wall -pedantic -ledit -ltermcap")
include_directories(/usr/local/include/ /usr/include)
link_directories(/usr/lib)
link_directories(/usr/local/lib)
add_executable(shell main.c errors.c util.c shellparser.c)
target_link_libraries(shell edit readline)
add_custom_target(shellparser DEPENDS ${CMAKE_SOURCE_DIR}/shellparser.c)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/shellparser.c COMMAND lemon -s ${CMAKE_SOURCE_DIR}/shellparser.y DEPENDS ${CMAKE_SOURCE_DIR}/shellparser.y)
add_dependencies(shell shellparser)
My project structure looks like:
$ tree
.
├── bquotes-test
├── bquotes-test.c
├── CMakeLists.txt
├── CommandEntry.h
├── do.h
├── errors.c
├── errors.h
├── integrationtest.sh
├── lemon.c
├── lempar.c
├── LICENSE
├── main.c
├── Makefile
├── openshell.h
├── README.md
├── shellparser.c
├── shellparser.h
├── shellparser.out
├── shellparser.y
├── stresstest.sh
├── tst_bquotes.check
├── tst_exp.sh
├── types.h
├── unittest.sh
└── util.c
0 directories, 25 files
My check test is
#include "openshell.h"
#include "errors.h"
#test myQtest
fail_unless(isBetweenQuotes(11, "abc'asdqerfdsdxcvc'xc") == 1, "isBetweenQuotes function borked");
fail_unless(isBetweenQuotes(5, "This has no quotes") == 0, "isBetweenQuotes2 function borked");
fail_unless(isBetweenQuotes(11, "This' is a sentence in 'quotes") == 1, "isBetweenQuotes3 function borked");
fail_unless(isBetweenQuotes(15, "\"This is a sentence in quotes\"") == 1, "isBetweenQuotes4 function borked");
/* gcc -Wall -o bquotes-test util.c errors.c bquotes-test.c -lcheck -lsubunit -lrt -pthread -lm */
/* checkmk tst_bquotes.check > bquotes-test.c */
I would try this. Create an external linux shell script, which has the line
checkmk tst_bquotes.check > bquotes-test.c
in it and call it something like prepare_test.sh. Then, I would add these lines to your CMakeLists.txt at the end:
execute_process(
COMMAND ./prepare_test.sh
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE prep_test_result)
add_executable(bquotes-test util.c errors.c bquotes-test.c )
target_link_libraries(bquotes-test check subunit rt pthread m)
add_test(start_test_bquotes bquotes-test)
include(CTest)
After you've called cmake, you can then start the tests with make test.

Geting source code structure in Makefile

I'm working on a C project, and I decided to put the source code and its objects in different directories. The root directory has something like that:
SmartC ▶ tree -L 1
.
├── built
├── doc
├── Makefile
├── README.md
├── src
├── tests
└── trash
So, inside both src and built directories, I put two others Makefiles to do the compile and link jobs.
The src directory (where I put the source code) has the following structure:
src
├── graph.c
├── graph.h
├── list.c
├── list.h
├── main.c
├── Makefile
├── node.c
├── node.h
├── tree.c
├── tree.h
└── types
├── complex.c
├── complex.h
├── matrix.c
└── matrix.h
and the built has the same structure, but it is intended to store all objects made by compilation.
My question is about my src/Makefile:
BINDIR = ../built/src
CC = gcc
CFLAGS = -g -Wall -O3
OBJECTS = \
$(BINDIR)/main.o \
$(BINDIR)/node.o \
$(BINDIR)/list.o \
$(BINDIR)/graph.o \
$(BINDIR)/tree.o \
$(BINDIR)/types/complex.o \
$(BINDIR)/types/matrix.o \
compile: $(OBJECTS)
$(BINDIR)/%.o: %.c
$(CC) -c $< -o $# $(CFLAGS)
This Makefile creates all the objects of the source code, inside src directory, and move them to built/src. But, every time I create a new source code file (*.c), I have to put the name of its object in this makefile, so it can be compiled. I'd like to do an automatic search, inside the src directory, and fill the "OBJECTS" variable with this search.
Is anyone has some idea of how to accomplish this? I mean, automatic search for source code inside an specific directory?
I even accept any other strategy rather than what I'm making.
=========== Answer ===============
I got the tip (in comments) about wildcards. So I did. Here is the solution I found.
src/Makefile
BINDIR = ../built/src
CC = gcc
CFLAGS = -g -Wall -O3
OBJECTS := $(patsubst %.c,$(BINDIR)/%.o,$(wildcard *.c */*.c))
compile: $(OBJECTS)
$(BINDIR)/%.o: %.c
$(CC) -c $< -o $# $(CFLAGS)
EDIT [Solved]
I like to do the following.
Create Variables to Each Directory of the Project
SRCDIR = src
OBJDIR = obj
LIBDIR = lib
DOCDIR = doc
HDRDIR = include
CFLAGS = -g -Wall -O3
Get Only the Internal Structure of SRCDIR Recursively
STRUCTURE := $(shell find $(SRCDIR) -type d)
Get All Files inside the STRUCTURE Variable
CODEFILES := $(addsuffix /*,$(STRUCTURE))
CODEFILES := $(wildcard $(CODEFILES))
Filter Out Only Specific Files
# Filter Only Specific Files
SRCFILES := $(filter %.c,$(CODEFILES))
HDRFILES := $(filter %.h,$(CODEFILES))
OBJFILES := $(subst $(SRCDIR),$(OBJDIR),$(SRCFILES:%.c=%.o))
# Filter Out Function main for Libraries
LIBDEPS := $(filter-out $(OBJDIR)/main.o,$(OBJFILES))
Now it is Time to create the Rules
compile: $(OBJFILES)
$(OBJDIR)/%.o: $(addprefix $(SRCDIR)/,%.c %.h)
$(CC) -c $< -o $# $(CFLAGS)
With this approach, you can see that I'm using the STRUCTURE variable only to get the files inside the SRCDIR directory, but it can be used for others purposes as well, like mirror the SRCDIR inside OBJDIR once STRUCTURE stores only the internal sub-directories. It is quite useful after clean operations like:
clean:
-rm -r $(OBJDIR)/*
NOTE: The compile rule only works well if for each *.c there is the corresponding *.h file (with the same base name, I mean).

Makefile: no rule to make target with variables

I'm trying to write a Makefile that when I add some deps in my application I just have to change DEPS_NAME variable, but something is wrong and I can't figure out what. I know that this is not the only problem with this Makefile, I just started to study this technology.
This is my project structure
application/
├── deps/
│ ├── buffer/
│ │ ├── buffer.c
│ │ └── buffer.h
│ └── other/
│ ├── other.c
│ └── other.h
├── objs/
├── application.c
└── Makefile
This is my Makefile
CC = gcc
APP_NAME = application
OBJS_PATH = objs
DEPS_PATH = deps
DEPS_NAME = buffer other
DEPS = $(patsubst %,$(OBJS_PATH)/%.o,$(DEPS_NAME))
$(OBJS_PATH)/%.o: $(DEPS_PATH)/%/%.c
$(CC) -o $# -c $^
$(APP_NAME): $(DEPS)
$(CC) -o $# $#.c $^
all: $(APP_NAME)
This is the error when i type make:
make: *** No rule to make target `objs/buffer.o', needed by `application'. Stop.
until you have determined the root cause of the problem, suggest a separate target for each *.c to *.o compile step.
you want the 'all' target to be the first target in the makefile.
(that is what a 'all' target is for, so can call the makefile with:
make
without specifying a target in the make file
Note: 'all' is a phony target (produces no file named 'all')
so should be written similar to:
.PHONY: all
all : $(app_name) $(DEPS)
When make performs the compile step(s)
It needs to know how to find the header files.
and since the header files are scattered,
it may be advisable to either 1) list all the paths/*.h files in the compile rule (simple but can result in unneeded compiles) or 2) generate dependancy files.(difficult, but best as the file count grows) or 3) write a separate compile rule for each source file. (least flexable, but easy for those new to make)
the compile rule needs to have parameters indicating where to find the header files. (in gcc, use '-I./other/.' and '-I./buffer/.)
I have never seen multiple stem references. Looks like it badly confuses the parser.
On a bright side it seems that
$(OBJS_PATH)/%.o: $($(DEPS_PATH)/%/%.c)
does the trick. Don't ask me why.
Putting the object files in the same directory of the source files I solved the problem with this Makefile
CC = gcc
CFLAGS = -Ideps
APP_NAME = application
DEPS_SOURCE = $(wildcard deps/*/*.c)
DEPS_OBJECT = $(DEPS_SOURCE:.c=.o)
all: $(APP_NAME)
$(APP_NAME): $(DEPS_OBJECT)
$(CC) $#.c -o $# $(DEPS_OBJECT) $(CFLAGS)
%.o: %.c
$(CC) -o $# -c $^
clean:
rm -f $(DEPS_OBJECT) $(APP_NAME)
.PHONY: all clean
Whit this solution I don't have to change the Makefile when I add other deps in the project.

Resources