I'm trying to make a custom OS for the raspberry pi. I follow this tutorial and used their Makefile, but when I try to compile it, I get this error:
echo objects/kernel.o objects/uart.o objects/stdio.o objects/stdlib.o objects/boot.o
objects/kernel.o objects/uart.o objects/stdio.o objects/stdlib.o objects/boot.o
./gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc -T linker.ld -o kernel.img -ffreestanding -O2 -nostdlib objects/kernel.o objects/uart.o objects/stdio.o objects/stdlib.o objects/boot.o
process_begin: CreateProcess(NULL, ./gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc -T linker.ld -o kernel.img -ffreestanding -O2 -nostdlib objects/kernel.o objects/uart.o objects/stdio.o objects/stdlib.o objects/boot.o, ...) failed.
make (e=2): Das System kann die angegebene Datei nicht finden. (Translation: The system can't find the given file)
Makefile:33: recipe for target 'build' failed
mingw32-make: *** [build] Error 2
and the Makefile:
# Don't use normal gcc, use the arm cross compiler
CC = ./gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc
# Set any constants based on the raspberry pi model. Version 1 has some differences to 2 and 3
ifeq ($(RASPI_MODEL),1)
CPU = arm1176jzf-s
DIRECTIVES = -D MODEL_1
else
CPU = cortex-a7
endif
CFLAGS= -mcpu=$(CPU) -fpic -ffreestanding $(DIRECTIVES)
CSRCFLAGS= -O2 -Wall -Wextra
LFLAGS= -ffreestanding -O2 -nostdlib
# Location of the files
KER_SRC = ../src/kernel
KER_HEAD = ../include
COMMON_SRC = ../src/common
OBJ_DIR = objects
KERSOURCES = $(wildcard $(KER_SRC)/*.c)
COMMONSOURCES = $(wildcard $(COMMON_SRC)/*.c)
ASMSOURCES = $(wildcard $(KER_SRC)/*.S)
OBJECTS = $(patsubst $(KER_SRC)/%.c, $(OBJ_DIR)/%.o, $(KERSOURCES))
OBJECTS += $(patsubst $(COMMON_SRC)/%.c, $(OBJ_DIR)/%.o, $(COMMONSOURCES))
OBJECTS += $(patsubst $(KER_SRC)/%.S, $(OBJ_DIR)/%.o, $(ASMSOURCES))
HEADERS = $(wildcard $(KER_HEAD)/*.h)
IMG_NAME=kernel.img
build: $(OBJECTS) $(HEADERS)
echo $(OBJECTS)
$(CC) -T linker.ld -o $(IMG_NAME) $(LFLAGS) $(OBJECTS)
$(OBJ_DIR)/%.o: $(KER_SRC)/%.c
mkdir -p $(#D)
$(CC) $(CFLAGS) -I$(KER_SRC) -I$(KER_HEAD) -c $< -o $# $(CSRCFLAGS)
$(OBJ_DIR)/%.o: $(KER_SRC)/%.S
mkdir -p $(#D)
$(CC) $(CFLAGS) -I$(KER_SRC) -c $< -o $#
$(OBJ_DIR)/%.o: $(COMMON_SRC)/%.c
mkdir -p $(#D)
$(CC) $(CFLAGS) -I$(KER_SRC) -I$(KER_HEAD) -c $< -o $# $(CSRCFLAGS)
clean:
rm -rf $(OBJ_DIR)
rm $(IMG_NAME)
run: build
qemu-system-arm -m 1024 -M raspi2 -serial stdio -kernel kernel.img
But because I've never worked with Makefiles before, I don't know what is wrong with the Makefile
Related
I'm trying to compile my C project using clang (I'm on MacOS Monterry) and a Makefile, but I keep getting the same error from clang in the command line:
> make
gcc -c src/ji.c src/main.c -o src/ji.o
clang: error: cannot specify -o when generating multiple output files
make: *** [src/ji.o] Error 1
These are the only files I have in the project so far:
src/main.c
src/ji.c
include/ji.h
The Makefile looks like this:
cc = gcc
src = $(wildcard src/*.c)
obj = $(src:.c=.o)
exec = ji
$(exec): $(obj)
$(cc) -Iinclude $< -o build/$#
%.o: %.c
$(cc) -c $(src) -o $#
clean:
-rm src/*.o
-rm ji
From YouTube videos I've seen, this should be the ideal Makefile for the project but no matter what I change I get the error.
There are a few issues:
-Iinclude needs to be on the %.o: %.c rule command
In %.o: %.c, we don't want $(src) but rather $<
We want patsubst to get the .o list obj
The $(exec) target doesn't match the -o option
The clean doesn't match the placement of the executable
Here's a refactored version (e.g. one way to do this--there are others):
cc = gcc
src = $(wildcard src/*.c)
obj = $(patsubst %.c,%.o,$(src))
exec = build/ji
$(exec): $(obj)
mkdir -p build
$(cc) $^ -o $#
%.o: %.c
$(cc) -c $< -o $# -Iinclude
clean:
rm -f src/*.o
rm -fr build
Here's the output of make:
gcc -c src/ji.c -o src/ji.o -Iinclude
gcc -c src/main.c -o src/main.o -Iinclude
mkdir -p build
gcc src/ji.o src/main.o -o build/ji
Here's the output of make clean:
rm -f src/*.o
rm -fr build
I am working on a project that uses some code written by someone else inside a folder called CommandParser. My project is called TCP_IP and inside it there is the CommandParser folder.
This is my makefile.
TARGET = $(BIN_DIR)/sim_tcp_ip
LIBS = -lpthread -L ./CommandParser -lcli
OBJS = $(OBJ_DIR)/prueba.o \
$(OBJ_DIR)/ListaEnlazada.o \
$(OBJ_DIR)/Grafico.o \
$(OBJ_DIR)/Net.o \
$(OBJ_DIR)/Topologias.o
BIN_DIR = ./bin
OBJ_DIR = ./obj
INC_DIR = ./inc
SRC_DIR = ./src
CFLAGS = -Wall -I$(INC_DIR)
$(TARGET): $(OBJS) CommandParser/libcli.a
mkdir -p $(BIN_DIR)
gcc $(CFLAGS) $(OBJS) -o $(TARGET) $(LIBS)
$(OBJ_DIR)/%.o : %.c
mkdir -p $(OBJ_DIR)
gcc -c -MD $(CFLAGS) $< -o $#
CommandParser/libcli.a:
(cd CommandParser; make)
-include $(OBJ_DIR)/*.d
.PHONY: clean
clean:
rm -rf $(OBJ_DIR) $(BIN_DIR)
(cd CommandParser; make clean)
all:
make
(cd CommandParser; make)
CommandParser has its own makefile.
CC=gcc
CFLAGS=-g -Wall
INCLUDES=-I .
CLILIB=libcli.a
TARGET:exe ${CLILIB}
OBJ=cmd_hier.o parser.o serialize.o string_util.o clistd.o clicbext.o gluethread/glthread.o ut/utinfra/ut_parser.o
exe:testapp.o ${CLILIB}
#echo "Building final executable"
# ${CC} ${CFLAGS} ${INCLUDES} testapp.o -o exe -L . -lcli -lpthread -lrt
cmd_hier.o:cmd_hier.c
#echo "Building cmd_hier.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} cmd_hier.c -o cmd_hier.o
parser.o:parser.c
#echo "Building parser.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} parser.c -o parser.o
gluethread/glthread.o:gluethread/glthread.c
#echo "Building gluethread/glthread.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} gluethread/glthread.c -o gluethread/glthread.o
serialize.o:serialize.c
#echo "Building serialize.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} serialize.c -o serialize.o
string_util.o:string_util.c
#echo "Building string_util.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} string_util.c -o string_util.o
clistd.o:clistd.c
#echo "Building clistd.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} clistd.c -o clistd.o
clicbext.o:clicbext.c
#echo "Building clicbext.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} clicbext.c -o clicbext.o
testapp.o:testapp.c
#echo "Building testapp.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} testapp.c -o testapp.o
ut/utinfra/ut_parser.o:ut/utinfra/ut_parser.c
#echo "Building ut/utinfra/ut_parser.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} ut/utinfra/ut_parser.c -o ut/utinfra/ut_parser.o
${CLILIB}: ${OBJ}
#echo "Building Library ${CLILIB}"
ar rs ${CLILIB} ${OBJ}
clean:
rm -f exe
rm -f *.o
rm -f gluethread/*.o
rm -f ut/utinfra/*.o
rm -f ${CLILIB}
rm -f CMD_HIST_RECORD_FILE.txt
install:
cp ${CLILIB} /usr/local/lib/
cp libcli.h /usr/include/
cp cmdtlv.h /usr/include/
uninstall:
rm -f /usr/local/lib/${CLILIB}
rm -f /usr/include/libcli.h
rm -f /usr/include/cmdtlv.h
When do make inside CommandParser, I don't get any error. However, something seems to be wrong with my makefile because if I do make in my TCP_IP folder, I get some undefined reference errors.
/usr/bin/ld: ./CommandParser/libcli.a(ut_parser.o): en la función ut_parser_init': /home/darinel/Documentos/Cursos/C++/TCP_IP/CommandParser/ut/utinfra/ut_parser.c:52: referencia a mq_open' sin definir
/usr/bin/ld: ./CommandParser/libcli.a(ut_parser.o): en la función run_test_case': /home/darinel/Documentos/Cursos/C++/TCP_IP/CommandParser/ut/utinfra/ut_parser.c:261: referencia a mq_timedreceive' sin definir
/usr/bin/ld: ./CommandParser/libcli.a(ut_parser.o): en la función cli_out': /home/darinel/Documentos/Cursos/C++/TCP_IP/CommandParser/ut/utinfra/ut_parser.c:517: referencia a mq_send' sin definir
collect2: error: ld returned 1 exit status
make: [makefile:16: bin/sim_tcp_ip] Error 1
The message shows that these errors come from the CommandParser code, and not from my code, even though it previously worked fine in the CommandParser folder.
It appears that the CommandParser library is looking for another library, that contains functions like mq_open, mq_send, and mq_timedreceive. If you look up these functions you'll see that they're provided by the realtime library, librt. So, you need to add the -lrt option to your link line.
Also, please pay close attention to the order of libraries on the link line. You should always order them highest-level to lowest-level. You have:
LIBS = -lpthread -L ./CommandParser -lcli
but -lpthread is a lower-level library so it should come after -lcli. Also, the modern way of building executables using threads is to use the -pthread option on BOTH the compile line AND the link line, so you should use:
LIBS = -pthread -L ./CommandParser -lcli -lrt
CFLAGS = -pthread -Wall -I$(INC_DIR)
I am getting this error while running make file to link the .o files.
command is $make build PLATFORM=HOST or $make build PLATFORM=MSP432,both gives the same error.
gcc main.o memory.o -DHOST -g -O0 -std=c99 -Wall -Werror -I../src/ -I../include/CMSIS/ -I../include/msp432/ -I../include/common/ -I../ -Wl,-Map=c1m2.map -L/usr/local/lib -T ../msp432p401r.lds -o c1m2.out
/usr/bin/ld: c1m2.out: Not enough room for program headers, try linking with -N
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
Makefile:79: recipe for target 'c1m2.out' failed
make: *** [c1m2.out] Error 1
and my makefile script:
include sources.mk
# Platform Overrides
PLATFORM = HOST
# Architectures Specific Flags
LINKER_FILE = msp432p401r.lds
CPU = cortex-m4
ARCH = armv7e-m
SPECS = nosys.specs
# Compiler Flags and Defines
# Conditional statements to choose the platform(host/msp432) else invalid platform message is diplayed.
ifeq ($(PLATFORM),HOST)
CC = gcc
CFLAGS = -DHOST
LD = ld
else
CC = arm-none-eabi-gcc
CFLAGS = -DMSP432 -mcpu=$(CPU) -march=$(ARCH) --specs=$(SPECS) -mfloat-abi=hard -mfpu=fpv4-sp-d16
LD = arm-none-eabi-ld
endif
TARGET = c1m2
LDFLAGS = -Wl,-Map=$(TARGET).map -T ../msp432p401r.lds
CPPFLAGS = -g -O0 -std=c99 -Wall -Werror $(INCLUDES)
OBJS = $(SRCS:.c=.o)
%.o : %.c
$(CC) -c $< $(CFLAGS) $(CPPFLAGS) -o $#
pre = $(SRCS:.c=.i)
%.i : %.c
$(CC) -c $< $(CFLAGS) $(CPPFLAGS) -E -o $#
asem =$(SRCS:.c=.asm):
%.asm : %.c
$(CC) -c $< $(CFLAGS) $(CPPFLAGS) -S -o $#
.PHONY: build
build: all
.PHONY: all
all: $(TARGET).out
$(TARGET).out: $(OBJS)
$(CC) $(OBJS) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $#
.PHONY: clean
clean:
rm -f $(OBJS) $(pre) $(asem) $(TARGET).out $(TARGET).map
I have created this for running both in HOST and the given processor(MSP432),please don't bother poor formatting.
I have started to move some of my atmega code into a static library for easier use in the future. This has some issues with ussing the library. I have compiled and linked againsed it, and it runs. The problem is the USART function that takes an array as input seems to just send noise to my com port. It worked fine before i put the code in a static lib.
Makefile library
## General Flags
PROJECT = june
MCU = atmega328p
TARGET = libJune.a
CC = avr-g++
F_CPU := 1200000LL
## Options common to compile, link and
assembly rules
COMMON = -fpack-struct -fshort-enums -
funsigned-char -funsigned-bitfields -
mmcu=$(MCU) -DF_CPU=$(F_CPU)
## Compile options common for all C
compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall -Os -MD -MP -MT -MF
#CFLAGS += -MD -MP -MT $(*F).o -MF
dep/$(#F)
## Objects that must be built in order
to link
OBJECTS := adc.o pwm.o message.o
messagehandler.o
messagetranslationsenter.o usart.o
## Build
all: $(TARGET)
## Compile
adc.o: adc.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
pwm.o: pwm.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
message.o: message.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
messagehandler.o: messagehandler.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
messagetranslationsenter.o:
messagetranslationsenter.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
usart.o: usart.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
## Archive into a library file (.a)
$(TARGET): $(OBJECTS)
avr-ar -r $(TARGET) $(OBJECTS)
## Clean target
.PHONY: clean
clean:
-rm -rf $(OBJECTS) $(TARGET) #dep/*
Makefile program
# the GNU make program
#
VERSION := 0.1
PROGRAM_NAME := heater$(VERSION)
# Chip and programmer
DEVICE_PROGRAMMER := usbtiny
CPU_AVRDUDE := m328p
MCU := atmega328p
F_CPU := 1200000LL
LIB_PATH := $(JUNE_ROOT)/avr
LIBS := -lJune -lm
INCLUDES := -I$(JUNE_ROOT)/avr
# FLAGS
CF := -c -Os -fpack-struct - fshort-enums -funsigned-char -funsigned- bitfields -mmcu=$(MCU) -DF_CPU=$(F_CPU)
$(INCLUDES)
LF := -Os -MD -MP -mmcu=$(MCU) -MT -static -L$(LIB_PATH) $(LIBS)
# TOOLS
CC := avr-g++
avrdude ?= avrdude
OBJECTS = main.o
all: $(PROGRAM_NAME)
main.o: main.cpp
$(CC) $(CF) -c $<
$(PROGRAM_NAME): $(OBJECTS)
$(MAKE) -C $(JUNE_ROOT)/avr
$(CC) -o $(PROGRAM_NAME) $(OBJECTS)
$(LF)
$(PROGRAM_NAME).hex: $(PROGRAM_NAME)
avr-objcopy -O ihex -R .eeprom
$(PROGRAM_NAME) $(PROGRAM_NAME).hex
.PHONY: flash
flash: programmedDevice
clean:
-rm -f *.o *.hex *.elf
programmedDevice_*.time
programmedDevice: $(PROGRAM_NAME).hex
$(avrdude) -c $(DEVICE_PROGRAMMER) -p
$(CPU_AVRDUDE) -v -U
flash:w:$(PROGRAM_NAME).hex
touch programmedDevice_$(CPU_GCC).time
$(PROGRAM_NAME)_$(CPU_GCC).hex:
$(Ofiles)
$(CC) $(LF) -o
$(PROGRAM_NAME)_$(CPU_GCC).elf
$(Ofiles)
$(avr_objcopy) -j .text -j .data -O
ihex $(PROGRAM_NAME)_$(CPU_GCC).elf
$(PROGRAM_NAME)_$(CPU_GCC).hex
clean:
-rm -f *.o *.hex *.elf
programmedDevice_*.time
$(MAKE) -C $(JUNE_ROOT)/avr clean
dumpchip_srec:
$(avrdude) -c $(DEVICE_PROGRAMMER)
-p $(CPU_AVRDUDE) -U
lfuse:r:lfuse_$(CPU_GCC).hex:i -U
hfuse:r:hfuse_$(CPU_GCC).hex:i -U
efuse:r:efuse_$(CPU_GCC).hex:i -U
eeprom:r:eeprom_$(CPU_GCC).hex:i -U
flash:r:flash_$(CPU_GCC).hex:i -U
lock:r:lock_$(CPU_GCC).hex:i -U
signature:r:sig_$(CPU_GCC).hex:i
dumpchip:
$(avrdude) -c $(DEVICE_PROGRAMMER) -p
$(CPU_AVRDUDE) -U
lfuse:r:lfuse_$(CPU_GCC).bin:r -U
hfuse:r:hfuse_$(CPU_GCC).bin:r -U
eeprom:r:eeprom_$(CPU_GCC).bin:r -U
flash:r:flash_$(CPU_GCC).bin:r -U
lock:r:lock_$(CPU_GCC).bin:r -U
signature:r:sig_$(CPU_GCC).bin:r -U
efuse:r:efuse_$(CPU_GCC).bin:r
check:
$(avrdude) -v -c
$(DEVICE_PROGRAMMER) -p $(CPU_AVRDUDE)
This is the part of the test software, that calls the usart function from the static library, but I can only read noise from the com port it sends data too.
while(true)
{
//
USART_putstring("Test");
_delay_ms(5000);
}
I think there is a compiler flag missing that i can not find. Everything is running fine if I add the usart files to the program and compile it. The problem is when the files are put in a static library.
Edit:
it works when i put the define F_CPU in the source file, instead of -DF_CPU=$(F_CPU) from the Makefile
I have an makefile but doesn't work. The error in terminal is this: cc -shared -o build/liblcthw.so src/lcthw/list.o
/usr/bin/ld: src/lcthw/list.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
src/lcthw/list.o: error adding symbols: Bad value
I need help to put the gcc comand gcc -shared -o target.so -fPIC target.c, i don't how to put the target.c instead list.o
This is the makefile:
CFLAGS=-g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
LIBS=-ldl $(OPTLIBS)
PREFIX?=/usr/local
SOURCES=$(wildcard src/**/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
TARGET=build/liblcthw.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
# The Target Build
all: $(TARGET) $(SO_TARGET) tests
dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
dev: all
$(TARGET): CFLAGS += -fPIC
$(TARGET): build $(OBJECTS)
ar rcs $# $(OBJECTS)
ranlib $#
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
build:
#mkdir -p build
#mkdir -p bin
# The Unit Tests
.PHONY: tests
tests: CFLAGS += $(TARGET)
tests: $(TESTS)
sh ./tests/runtests.sh
valgrind:
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
# The Cleaner
clean:
rm -rf build $(OBJECTS) $(TESTS)
rm -f tests/tests.log
find . -name "*.gc*" -exec rm {} \;
rm -rf `find . -name "*.dSYM" -print`
# The Install
install: all
install -d $(DESTDIR)/$(PREFIX)/lib/
install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
# The Checker
BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
check:
#echo Files with potentially dangerous functions.
#egrep $(BADFUNCS) $(SOURCES) || true
Your objects for liblcthw.a are built with -fPIC. Objects for liblcthw.so are not built with this setting.
Try changing rule:
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
to:
$(SO_TARGET): $(TARGET)
$(CC) -shared -o $# $^
Since the required objects are already in liblcthw.a.
Or, alternatively:
$(SO_TARGET): CFLAGS += -fPIC
$(SO_TARGET): $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)