This is weird. The compiler throws this warning though everything works as expected.
This is the makefile that throws the warning:
TARGET = $(notdir $(shell pwd))
LIBS = -lm -lev3dev-c
D_BIN = Build-Assets
ifeq ($(OS),Windows_NT)
LIBS := $(LIBS) -lws2_32
D_BIN := $(D_BIN)/mingw
endif
D_H = ../../source/ev3
CFLAGS = $(addprefix -I, $(D_H)) -O2 -std=gnu99 -W -Wall -Wno-comment
ifeq ($(OS),Windows_NT)
CC = gcc
else
CC = arm-linux-gnueabi-gcc
endif
ifeq ($(OS),Windows_NT)
E_BIN = .exe
else
E_BIN =
endif
F_BIN = $(TARGET)$(E_BIN)
OBJECTS = $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard MotorControl/*.c)))
.PHONY: default all clean
default: $(F_BIN)
all: default
$(OBJECTS): $(D_BIN)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
.PRECIOUS: $(F_BIN) $(OBJECTS)
$(F_BIN): $(OBJECTS)
$(CC) $(OBJECTS) -c -Wall $(LIBS) -o $#
clean:
-rm -f $(D_BIN)/*.o
-rm -f $(F_BIN)
I should add that I have no idea what I'm doing... I am just starting out with C and those damn makefiles are very overwhelming.
The -c option skips the final link and produces a relocatable object file:
$(F_BIN): $(OBJECTS)
$(CC) $(OBJECTS) -c -Wall $(LIBS) -o $#
This is why linker input files are not used at this stage. You should be able to remove the -c option, and the command will produce an executable as a result.
Related
I've been trying to get my Raspberry Pi 4 OS (not Linux or anything, I'm making an OS from scratch) to work.
The Makefile has this error when I use the command "make":
rm -rf objects
rm -rf SuperPiOS.elf
rm SuperPiOS.img
rm: cannot remove 'SuperPiOS.img': No such file or directory
make: *** [Makefile:110: clean] Error 1
I can't figure out why it wouldn't work though.
Here's the Makefile:
CFLAGS= -Wall -O2 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
CXXFLAGS= -ggdb3 -O0 -Wall -O2 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
CSRCFLAGS= -O2 -Wall -Wextra
LFLAGS= -ffreestanding -O2 -nostdlib
IMG_PATH= ../
CFILES= $(wildcard *.c)
OFILES= $(CFILES:.c=.o)
GCCFLAGS= -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
GCCPATH= gcc-arm-10.2-2020.11-x86_64-aarch64-none-elf
GCCPATHAARCH= $(GCCPATH)/aarch64-none-elf/bin
GCCPATHBIN= $(GCCPATH)/bin
ASMCFLAGS= -f elf32 -F dwarf -g -w+all
ASM= -s
# Location of the files
KER_SRC = ../src/kernel
KER_MENU_SRC = ../src/kernel/menu
KER_HEAD = ../include
COMMON_SRC = ../src/common
UI_IMAGES = ../images/ui
SPE_GAMES = ../spe_games
DINOBYTE = $(SPE_GAMES)/dinobyte
OBJ_DIR = objects
ASMSOURCES = $(wildcard $(KER_SRC)/*.s)
KERSOURCES = $(wildcard $(KER_SRC)/*.c)
#KERSOURCES = $(wildcard $(KER_SRC)/$(ARCHDIR)/*.c)
COMMONSOURCES = $(wildcard $(COMMON_SRC)/*.c)
KERSOURCESCPP = $(wildcard $(KER_SRC)/*.cpp)
DINOBYTESOURCES = $(wildcard $(DINOBYTE)/src/*.cpp)
#KERSOURCESCPP = $(wildcard $(KER_SRC)/$(ARCHDIR)/*.cpp)
#KERMENUSOURCESC = $(wildcard $(KER_MENU_SRC)/*.c)
#KERMENUSOURCESCPP = $(wildcard $(KER_MENU_SRC)/*.cpp)
UISOURCES = $(wildcard $(UI_IMAGES)/*.png)
OBJECTS = $(patsubst $(KER_SRC)/%.s, $(OBJ_DIR)/%.o, $(ASMSOURCES))
#OBJECTS += $(patsubst $(KER_SRC)/%.s, $(OBJ_DIR)/%.o, $(ASMSOURCES))
OBJECTS += $(patsubst $(KER_SRC)/%.c, $(OBJ_DIR)/%.o, $(KERSOURCES))
OBJECTS += $(patsubst $(KER_SRC)/%.cpp, $(OBJ_DIR)/%.o, $(KERSOURCESCPP))
OBJECTS += $(patsubst $(COMMON_SRC)/%.c, $(OBJ_DIR)/%.o, $(COMMONSOURCES))
#OBJECTS += $(patsubst $(KER_MENU_SRC)/%.c, $(OBJ_DIR)/%.o, $(KERMENUSOURCESC))
#OBJECTS += $(patsubst $(KER_MENU_SRC)/%.cpp, $(OBJ_DIR)/%.o, $(KERMENUSOURCESCPP))
#OBJECTS += $(patsubst $(UI_IMAGES)/%.png, $(OBJ_DIR)/%.o, $(UISOURCES))
#Dinobyte objects [include Dinobyte headers here] (do later)
#OBJECTS += $(patsubst $(DINOBYTESOURCES)/src/%.cpp, $(OBJ_DIR)/%.o, $(DINOBYTESOURCES))
#Headers
HEADERS = $(wildcard $(KER_HEAD)/*.h)
IMG_NAME=SuperPiOS
#build: $(OBJECTS) $(HEADERS)
#$(CC) -T linker.ld -o $(IMG_NAME).elf $(LFLAGS) $(OBJECTS) #needs indent
#$(OBJCOPY) $(IMG_NAME).elf -O binary $(IMG_NAME).img #needs indent
#$(OBJ_DIR)/%.o: $(KER_SRC)/%.s
#mkdir -p $(#D) #needs indent
#$(CC) $(CFLAGS) -I$(KER_SRC) -c $< -o $# #needs indent
$(OBJ_DIR)/%.o: $(KER_SRC)/%.s
$(GCCPATHBIN)/aarch64-none-elf-gcc $(GCCFLAGS) -c $(KER_SRC) -o $(OBJ_DIR)
$(OBJ_DIR)/%.o: $(KER_SRC)/%.c
$(GCCPATHBIN)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $#
$(OBJ_DIR)/%.o: $(KER_SRC)/$(ARCHDIR)/%.c
$(GCCPATHBIN)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $#
$(OBJ_DIR)/%.o: $(KER_SRC)/%.cpp
$(GCCPATHBIN) arm-none-eabi-cpp $(GCCFLAGS) -c $< -o $#
$(OBJ_DIR)/%.o: $(KER_SRC)/$(ARCHDIR)/%.cpp
$(GCCPATHBIN)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $#
$(OBJ_DIR)/%.o: $(COMMON_SRC)/%.c
$(GCCPATHBIN)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $#
#$(OBJ_DIR)/%.o: $(KER_MENU_SRC)/%.c
# mkdir -p $(#D)
# $(CC) $(CFLAGS) -I$(KER_SRC) -I$(KER_HEAD) -c $< -o $# $(CSRCFLAGS)
#$(OBJ_DIR)/%.o: $(KER_MENU_SRC)/%.cpp
# mkdir -p $(#D)
# $(CC) $(CXXFLAGS) -I$(KER_SRC) -I$(KER_HEAD) -c $< -o $# $(CSRCFLAGS)
$(IMG_NAME)%.img: $(OBJECTS) $(HEADERS)
$(GCCPATHBIN)/aarch64-none-elf-ld -nostdlib -nostartfiles $(OBJECTS) -T linker.ld -o $(IMG_NAME).elf
$(GCCPATHBIN)/aarch64-none-elf-objcopy -O binary $(IMG_NAME).elf $(IMG_NAME).img
clean:
rm -rf $(OBJ_DIR)
rm -rf $(IMG_NAME).elf
rm $(IMG_NAME).img
run: build
qemu-system-arm -m 128 -no-reboot -M raspi4 -serial stdio -kernel kernel.elf
dbg:
$(GDB) kernel.elf
dbgrun: build gdbinit
qemu-system-arm -m 128 -no-reboot -M raspi4 -serial stdio -kernel kernel.elf -S -s
.PHONY: gdbinit
gdbinit:
echo "target remote localhost:1234" > .gdbinit
echo "break kernel_main" >> .gdbinit
You have two problems. The most obvious one is that this command:
rm SuperPiOS.img
is failing because that's how the rm program is defined: if the file you ask it to delete doesn't exist then rm will fail. If you don't want that to happen, add the -f option:
rm -f SuperPiOS.img
Now if the file doesn't exist, rm will silently succeed. You can examine the man pages for the rm program.
However, the higher level question you are probably asking is, why when I run make is it running the clean rule?
That's because make, if you don't specify what to build on the command line, always builds the first explicit target. In this makefile the first explicit target you defined is clean, so that's what's built. This is almost certainly not what you want. You should figure out what target you want to build when you run make with no arguments and put the rule for that target as the first explicit target in your makefile.
Other than this rule it normally doesn't matter much what order rules come in (if you have multiple pattern rules that could all build the same target, for example multiple pattern rules to build %.o, then order can matter there).
I'm trying to use GCC (linux) with a makefile to compile my project.
I get the following error
"No rule to make target 'output/src/main.o', needed by 'test'. Stop."
This is the makefile:
COMPILE_PREX ?=
CC = $(COMPILE_PREX)gcc
SOURCE = $(wildcard src/*.c)
OBJS = $(addprefix ./output/, $(patsubst %.c, %.o, $(SOURCE)))
INCLUDES = -I ./src
CFLAGS += -O2 -Wall -g
LDFLAGS += -lpthread
TARGET = test
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $(TARGET)
%.o: %.c
#mkdir -p ./output
$(CC) $(CFLAGS) $(INCLUDES) -o $(addprefix ./output/, $#) -c $<
clean:
rm -rf ./output
This should work. Note the use of mkdir $(#D) to create output directories as needed.
COMPILE_PREX ?=
CC = $(COMPILE_PREX)gcc
SOURCE = $(wildcard src/*.c)
OBJS = $(addprefix output/, $(patsubst %.c, %.o, $(SOURCE)))
INCLUDES = -I src
CFLAGS += -O2 -Wall -g
LDFLAGS += -lpthread
TARGET = test
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $(TARGET)
output/%.o: %.c
#mkdir -p $(#D)
$(CC) $(CFLAGS) $(INCLUDES) -o $# -c $<
clean:
rm -rf output
Running it here with make clean test:
rm -rf output
gcc -O2 -Wall -g -I src -o output/src/hello.o -c src/hello.c
gcc output/src/hello.o -lpthread -o test
I am facing a problem with my makefile. I am trying to compile .c; .cpp and .S files from ./src/. The objects should go into ./obj/ and the binaries into ./bin/. With my current file, it tries to searches for files in ./src/, but tries to compile objectfiles for each extension. So for example, if it finds kernel.cpp, it will try to compile kernel.S and kernel.c, but they are not there, so i get an error.
Here is my code:
TARGET = kernel
CC = gcc
LD = ld
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SRCS = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.cpp) $(wildcard $(SRCDIR)/*.S)
HDR = $(wildcard $(SRCDIR)/*.h)
OBJS = $(SRCS:$(SRCDIR)/%.c=$(OBJDIR)/%.o) $(SRCS:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o) $(SRCS:$(SRCDIR)/%.S=$(OBJDIR)/%.o)
rm = rm -f
ASFLAGS = -m64
CFLAGS = -m64 -Wall -g -fno-stack-protector -nostdinc
LDFLAGS = -m elf_x86_64 -Ttext=0x100000
$(BINDIR)/$(TARGET): $(OBJS)
$(LD) $(OBJS) $(LDFLAGS) -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.S
$(CC) $(ASFLAGS) -c $< -o $#
.PHONY: clean
clean:
$(rm) $(OBJS)
.PHONY: remove
remove:
$(rm) $(BINDIR)/$(TARGET)
I might try to separate SRCS into SRCS_Cpp and so on... But i don't know if that's the best solution. I am pretty new to makefiles^^
I think i found the solution^^
TARGET = kernel
CC = gcc
LD = ld
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SRCS_c = $(wildcard $(SRCDIR)/*.c)
SRCS_cpp = $(wildcard $(SRCDIR)/*.cpp)
SRCS_S = $(wildcard $(SRCDIR)/*.S)
HDR = $(wildcard $(SRCDIR)/*.h)
OBJS = $(SRCS_c:$(SRCDIR)/%.c=$(OBJDIR)/%_c.o) $(SRCS_cpp:$(SRCDIR)/%.cpp=$(OBJDIR)/%_cpp.o) $(SRCS_S:$(SRCDIR)/%.S=$(OBJDIR)/%_S.o)
rm = rm -f
ASFLAGS = -m64
CFLAGS = -m64 -Wall -g -fno-stack-protector -nostdinc
LDFLAGS = -m elf_x86_64 -Ttext=0x100000
$(BINDIR)/$(TARGET): $(OBJS)
$(LD) $(OBJS) $(LDFLAGS) -o $#
$(OBJDIR)/%_c.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR)/%_cpp.o : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR)/%_S.o : $(SRCDIR)/%.S
$(CC) $(ASFLAGS) -c $< -o $#
.PHONY: clean
clean:
$(rm) $(OBJS)
.PHONY: remove
remove:
$(rm) $(BINDIR)/$(TARGET)
Is there something i do wrong? I am trying to compile a kernel without the use of a cross-compiler^^
I am kind of new in the use of make.
I have a library written in C which is in the folder folder1
Where these files are there is also a makefile which is the following:
PREFIX ?= /usr/local
CC = gcc
AR = ar
CFLAGS = -std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4
APRILTAG_SRCS := $(shell ls *.c common/*.c)
APRILTAG_HEADERS := $(shell ls *.h common/*.h /usr/include/flycapture/*.h)
APRILTAG_OBJS := $(APRILTAG_SRCS:%.c=%.o)
TARGETS := libapriltag.a libapriltag.so
.PHONY: all
all: $(TARGETS)
#$(MAKE) -C example all
.PHONY: install
install: libapriltag.so
#chmod +x install.sh
#./install.sh $(PREFIX)/lib libapriltag.so
#./install.sh $(PREFIX)/include/apriltag $(APRILTAG_HEADERS)
#sed 's:^prefix=$$:prefix=$(PREFIX):' < apriltag.pc.in > apriltag.pc
#./install.sh $(PREFIX)/lib/pkgconfig apriltag.pc
#rm apriltag.pc
#ldconfig
libapriltag.a: $(APRILTAG_OBJS)
#echo " [$#]"
#$(AR) -cq $# $(APRILTAG_OBJS)
libapriltag.so: $(APRILTAG_OBJS)
#echo " [$#]"
#$(CC) -fPIC -shared -o $# $^
%.o: %.c
#echo " $#"
#$(CC) -o $# -c $< $(CFLAGS)
.PHONY: clean
clean:
#rm -rf *.o common/*.o $(TARGETS)
#$(MAKE) -C example clean
Then, in the folder example I have some example which I can just run by giving the following command in the terminal:
./opencv_demo
or
./apriltag_demo
In this folder example I have another makefile which is the following:
CC = gcc
CXX = g++
CPPFLAGS = -I..
CFLAGS = -std=gnu99 -Wall -Wno-unused-parameter -Wno-unused-function -O4
CXXFLAGS = -Wall -O4
LDFLAGS = -Lusr/include/flycapture -lpthread -lm
INC_DIR = /usr/include/flycapture
TARGETS := apriltag_demo opencv_demo
.PHONY: all
all: apriltag_demo opencv_demo
apriltag_demo: apriltag_demo.o ../libapriltag.a
#echo " [$#]"
#$(CC) -o $# $^ $(LDFLAGS)
opencv_demo: opencv_demo.o ../libapriltag.a /usr/include/flycapture/Error.h
#echo " [$#]"
#$(CXX) -o $# $^ $(LDFLAGS) `pkg-config --libs opencv`
%.o: %.c
#echo " $#"
#$(CC) -o $# -c $< $(CFLAGS) $(CPPFLAGS)
%.o: %.cc
#echo " $#"
#$(CXX) -o $# -c $< $(CXXFLAGS) $(CPPFLAGS)
.PHONY: clean
clean:
#rm -rf *.o $(TARGETS)
If I do make in the folder1 I get the following error:
opencv_demo.o: In function `main':
opencv_demo.cc:(.text.startup+0x24e): undefined reference to `FlyCapture2::Error::Error()'
opencv_demo.cc:(.text.startup+0x2a7): undefined reference to `FlyCapture2::Error::~Error()'
opencv_demo.cc:(.text.startup+0x11a0): undefined reference to `FlyCapture2::Error::~Error()'
collect2: error: ld returned 1 exit status
make[1]: *** [opencv_demo] Error 1
make[1]: Leaving directory `/home/fschiano/Repositories/apriltag2/example'
make: *** [all] Error 2
If I am not wrong this error tells me that I did not include a library.
In the file opencv_demo.cc I did:
#include "flycapture/FlyCapture2.h"
#include "flycapture/Error.h"
using namespace FlyCapture2;
Headers which are in /usr/include/flycapture a folder which contains all the headers needed for what I need in the file opencv_demo.cc.
I don't know why it is not working, someone is able to help me?
I think I should write in the makefile where to search for the libraries but I don't know how.
I tried to write the following things in the makefile separately but they are not working :
LDFLAGS = -Lusr/include/flycapture -lpthread -lm
INC_DIR = /usr/include/flycapture
DEPS = $(INC_DIR)/Error.h
I have wrote a makefile to compile a dynamic library. However, output .so file does not contains all of the methods.
I have used this Makefile:
CC=g++
CFLAGS=-fPIC -g
LDFLAGS=-shared
SRCDIR=src
SOURCES=$(shell echo $(SRCDIR)/*.cpp)
HEADERS=$(shell echo $(SRCDIR)/*.h)
OBJECTS=$(SOURCES:.cpp=.o)
LIBDIR=lib
INCDIR=include
LIBRARIES=-lboost_filesystem -lboost_system -lopencv_core -lopencv_highgui -lopencv_imgproc
OUT=$(LIBDIR)/libAgeGender.so
all: $(SOURCES) $(HEADERS) $(OUT)
.cpp.o:
$(CC) $(CFLAGS) $< -o $# $(LDFLAGS)
$(OUT): $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) $(LIBRARIES) -o $# $(LDFLAGS)
clean:
rm -f $(SRCDIR)/*.o *~ $(SRCDIR)/*~ $(OUT)
Then i executed this command to see functions inside of an .o file.
nm SDaisy.o | grep ' T '
00000000000070d6 T _ZN6SDaisy11convolutionERKN2cv3MatESt6vectorIfSaIfEEi
000000000000933e T _ZN6SDaisy12extractDaisyERKN2cv3MatE
0000000000007498 T _ZN6SDaisy14gaussianFilterERKN2cv3MatEff
000000000000854a T _ZN6SDaisy16smoothHistogramsERN2cv3MatE
000000000000c088 T _fini
0000000000005960 T _init
When we look into shared object, we can't see methods.
$ nm libAgeGender.so | grep ' T '
0000000000000578 T _fini
0000000000000438 T _init
How can i make it correctly?
Use the right variables and functions, and let make handle the compilation of .o files.
SRCDIR := src
LIBDIR := lib
INCDIR := include
SRC := $(wildcard $(SRCDIR)/*.cpp)
OBJ := $(SRC:.cpp=.o)
OUT := $(LIBDIR)/libAgeGender.so
CXXFLAGS := -fPIC -g
LDFLAGS := -shared
LDLIBS := -lboost_filesystem -lboost_system \
-lopencv_core -lopencv_highgui -lopencv_imgproc
all: $(OUT)
$(OUT): $(OBJ)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#