Makefile for IAR. List of src - linux

I have variable in my Makefile:
SRCP = \
main.c \
lib1/src/file1.c \
lib2/src/file2.c
Folders lib1/src and lib2/src may consist other sources, but I need compil only files in SRCP var.
I know one variant:
OBJ_DIR = ./Release/Obj
OBJ = $(SRC:.c=.o)
$(OBJ): $(SRCP)
for source in $(SRCP); do \
$(CC) $(CLAGS) -c $$source -o $(OBJ_DIR)/$#; \
done
But not informative. In console I see $source instead main.c (or any name).
My makefile with errors:
.PHONY: all clean
PROJECT = hello
IAR_TARGET = ./Release
EXE_DIR = $(IAR_TARGET)/Exe
OBJ_DIR = $(IAR_TARGET)/Obj
COMPILE_OPTS = -mcpu=cortex-m3 -mthumb -Wall -g -O0
INCLUDE_DIRS = -I . \
-I lib/inc
SRCP = \
main.c \
lib/src/stm32f10x_tim.c \
lib/src/stm32f10x_adc.c
LIB = -L ./lib/src
SRC := $(notdir $(SRCP))
OBJ_FILES := $(addprefix $(OBJ_DIR)/,$(notdir $(SRCP:.c=.o)))
CC = arm-none-eabi-gcc
CFLAGS = $(COMPILE_OPTS) $(INCLUDE_DIRS)
# mkdir -p $(EXE_DIR) $(OBJ_DIR)
all: $(EXE_DIR)/$(PROJECT).elf
# Linker invocation
$(EXE_DIR)/$(PROJECT).elf: $(OBJ_FILES)
$(CC) $(CFLAGS) $(OBJ_FILES) -o $(EXE_DIR)/$(PROJECT).elf
# Rules
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
clean:
rm -rf $(IAR_TARGET)
Error: make: *** No rule to make target 'Release/Obj/main.o', needed by 'Release/Exe/hello.elf'. Stop.
What is the correct version you know?

I don't have any specific experience with IAR projects. But I guess I can help you with the Makefile.
The main changes I propose are:
Change the definition of OBJ_FILES such that it contains a list of the object files with the proper path name, e.g. ./Release/Obj/file1.o. notdir removes the directory, addprefix adds the new directory.
Add a pattern rule how to convert a .c file into a .o file. As object files are a dependency of the final file (a .elf file in this example) and as there are no explicit rules to build the these object file, make will use the pattern rule to build them.
Most likely, GNU make is required for this makefile.
SRCP = \
main.c \
lib/src/stm32f10x_tim.c \
lib/src/stm32f10x_adc.c
OBJ_DIR = ./Release/Obj
OBJ_FILES := $(addprefix $(OBJ_DIR)/,$(notdir $(SRCP:.c=.o)))
# Linker invocation
$(OUTPUT_DIR)/$(PROJECT).elf: $(OBJ_FILES)
$(CC) $(LDFLAGS) $(OBJ_FILES) $(STD_LIBS) -o $(OUTPUT_DIR)/$(PROJECT).elf
# Rules
$(OBJDIR)/%.o: ./%.c
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR)/%.o: lib/src/%.c
$(CC) $(CFLAGS) -c $< -o $#

I know!
I have list of files with path:
SRCP := \
main.c \
lib/src/stm32f10x_tim.c \
lib/src/stm32f10x_adc.c
How to get .c file with path by object name?
Look:
OBJ_DIR=Release/Obj
# Rules
%.o:
#echo creating $# ...
$(CC) $(CFLAGS) -c $(filter %$(subst .o,.c,$#), $(SRCP)) -o $(OBJ_DIR)/$#
How to work this $(filter %$(subst .o,.c,$#), $(SRCP))?
For example, $# have stm32f10x_adc.o
$(subst .o,.c,$#) change .o to .c, so we have stm32f10x_adc.c. Very important! This string do not have spaces (like I like:) ). I do mistake, when write $(subst .o, .c, $#). It is not clear for me (:
%$(subst .o,.c,$#). % work with filter.
$(filter %$(subst .o,.c,$#), $(SRCP)) take %stm32f10x_adc.c from $(SRCP) with path. And... We have lib/src/stm32f10x_adc.c!
Thankyou for the help!

Related

makefile with multiple folders

I have a question about makefiles, below is my project structure.
enter image description here
Below is my makefile
.PHONY:clean install distclean
INCLUDEPATH = ../include
LIBRARYPATH = ../lib
LIBNAME = ../lib/libglfw.3.3.dylib ../lib/libGL.dylib ../lib/libGLU.dylib
# third part libary
EXTERNALDIR = ../External
IMGUIDIR = ../External/Imgui/include
GLADDIR = ../External/glad/include
IMGUIZMODIR = ../External/Imguizmo
GLFWDIR = ../External/glfw
GLADSRC = ../External/glad/src
IMGUISRC = ../External/Imgui/src
IMGUIZMOSRC = ../External/Imguizmo
CC = gcc
C++ = g++ -std=c++17
C++FLAGS = -c -I$(INCLUDEPATH) -I$(EXTERNALDIR) -I$(IMGUIDIR)-I$(GLADDIR) -I$(IMGUIZMODIR) -I$(GLFWDIR)
CCFLAGS = -c -I$(INCLUDEPATH) -I$(GLADDIR)
LDFLAGS = -L$(LIBRARYPATH) $(LIBNAME)
TARGET = app
INSTALLPATH = /usr/bin/
RM = rm -rf
MV = sudo mv $(TARGET) $(INSTALLPATH)
CCFILES = $(wildcard *.c $(GLADSRC)/*.c)
C++FILES = $(wildcard *.cpp $(IMGUISRC)/*.cpp $(FILEDLGSRC)/*.cpp $(IMGUIZMOSRC)/*.cpp)
OBJFILES = $(patsubst %.c,%.o,$(CCFILES)) $(patsubst %.cpp,%.o,$(C++FILES))
$(TARGET):$(OBJFILES)
$(C++) $^ $(LDFLAGS) -o $#
%.o:%.c
$(CC) $(CCFLAGS) $<
%.o:%.cpp
$(C++) $(C++FLAGS) $<
clean:
$(RM) $(TARGET)
$(RM) $(OBJFILES)
install:
$(MV)
distclean:
$(RM) $(INSTALLPATH) $(TARGET)
echo:
-#echo $(SRCFILE)
-#echo $(DESFILE)
removfile:
-#rm clean
-#rm clean_01
-#rm clean_02
When I run the makefile, I will generate all the .o files in the src/ directory, which will cause the .o files to not be found in the subsequent compilation process and the compilation will fail. Any tips to fix it. For example, how do I put the .o files generated by .cpp in the external directory in the external directory instead of the src directory.
It's just a matter of changing the list of object files and the rules for building them:
OBJFILES = $(patsubst %.c,$(EXTERNALDIR)/%.o,$(CCFILES)) $(patsubst %.cpp,$(EXTERNALDIR)/%.o,$(C++FILES))
$(EXTERNALDIR)/%.o:%.c
$(CC) $(CCFLAGS) $< -o $#
$(EXTERNALDIR)/%.o:%.cpp
$(C++) $(C++FLAGS) $< -o $#

Can anyone explain me this makefile example?

# Makefile to compare sorting routines
BASE = /home/blufox/base
CC = gcc
CFLAGS = -O –Wall
EFILE = $(BASE)/bin/compare_sorts
INCLS = -I$(LOC)/include
LIBS = $(LOC)/lib/g_lib.a \
$(LOC)/lib/h_lib.a
LOC = /usr/local
OBJS = main.o another_qsort.o chk_order.o \
compare.o quicksort.o
$(EFILE): $(OBJS)
#echo “linking …”
#$(CC) $(CFLAGS) –o $# $(OBJS) $(LIBS)
$(OBJS): compare_sorts.h
$(CC) $(CFLAGS) $(INCLS) –c $*.c
# Clean intermediate files
clean:
rm *~ $(OBJS)
variables substitute to form,
gcc -O –Wall -o /home/blufox/base/bin/compare_sorts main.o another_qsort.o chk_order.o compare.o quicksort.o main.c another_qsort.c chk_order.c compare.c
for eg:
$(OBJS) = main.o another_qsort.o chk_order.o compare.o quicksort.o

Make: No rule to make target 'part2.d', needed by MahApp

I have the following Makefile:
SOURCES = part1.cpp part2.cpp main.cpp
OBJECTS = ${SOURCES:.cpp=.o}
DEPS = ${SOURCES:.cpp=.d}
CXX = g++
CXXFLAGS = -Wall -I -std=c++11
ExecutableName = Partsapp
BUILD_DIR = build/host
MahApp: $(BUILD_DIR)/$(DEPS) $(BUILD_DIR)/$(OBJECTS)
$(CXX) $(CXXFLAGS) -o $# $(BUILD_DIR)/$(OBJECTS)
build/host/%.d: ./%.cpp
$(CXX) -MT$(#:.d=.o) -MM $(CXXFLAGS) $^ > $#
-include build/host/$(DEPS)
clean:
rm -f $(OBJECTS) $(DEPS) MahApp
Now, whenever I try to run it, I get the following error:
No rule to make target 'part2.d', needed by 'MahApp'. Stop.
Now, the funny thing is that it does manage to create part1.d correctly from the pattern matching rule, however after that it just seizes to work, and I just can't figure out why!
Any help would be much appreciated :)
SOURCES = part1.cpp part2.cpp main.cpp
...
DEPS = ${SOURCES:.cpp=.d}
...
BUILD_DIR = build/host
MahApp: $(BUILD_DIR)/$(DEPS) ...
...
DEPS expands to part1.d part2.d main.d, so $(BUILD_DIR)/$(DEPS) expands to build/host/part1.d part2.d main.d, and Make is telling you it can't find part2.d.
The construction you want is:
BUILD_DIR = build/host
DEPS = $(patsubst %.cpp, $(BUILD_DIR)/%.d, $(SOURCES))
(There are other ways to do it.) And the way to examine your variables to see if they are what you think they are is like this:
$(info $(DEPS))

Errors in make file : *** missing separator. Stop

I am facing errors in make file in CentOS 6.02 64 bit. I need to know what should be done to make the makefile workable. Any suggestion will be greatly helpful. My make file is pasted below: -
#
.SUFFIXES: .cc $(.SUFFIXES)
ALL = libpal.a
#all = $(ALL)
all: $(ALL)
.cpp.o:
$(C++) -o $# -c $(PROF) $(CFLAGS) $*.cpp
.cc.o:
$(C++) -o $# -c $(PROF) $(CFLAGS) $*.cc
.c.o:
$(CC) -o $# -c $(PROF) $(CFLAGS) $*.c
top_srcdir = ..
OPENSSL_LIB_DIR = ../../ThirdPartyLibs/openssl-0.9.8e/include
BOOST_DIR = ../../ThirdPartyLibs/boost/stage/lib
BOOST_INCLUDE_DIR = ../../ThirdPartyLibs/boost
CC = gcc
C++ = g++
CCOPT = -Os -Wall -Wno-deprecated
CCOPT_DEBUG = -Wall -g -Wno-deprecated
PROF =
STATIC = -static
INCLUDE = \
-I./usr/include/sys
-I./Headers \
-I$(top_srcdir)/PAL/Headers \
-I$(top_srcdir)/BaseMulti/Headers \
-I$(top_srcdir)/NetworkMulti/Headers \
-I$(top_srcdir)/RTP/Headers \
-I$(BOOST_INCLUDE_DIR) \
-I$(OPENSSL_LIB_DIR) \
LIBDIRS = \
-L$(BOOST_DIR) \
#XXX NLAYER define / MB_DEBUG
DEFINE = -D_LINUX -DDEBUGLOG -D_INDENT_DB_PRINT -fsigned-char -fno-inline -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D_POSIX_PER_PROCESS_TIMER_SOURCE -D_PTHREADS -DUNICODE #-DDISABLE_LOG
SHLIB_SUFFIX = .so
SHLIB_LD = gcc -shared
SHLIB_LD_LIBS =
SHLIB_CFLAGS = -fPIC
BFLAGS = $(DEFINE) $(INCLUDE)
CFLAGS = $(CCOPT) $(BFLAGS)
OBJ_C =
OBJ_CC = \
./Sources/PALsystime.o \
./Sources/PALdebug.o \
./Sources/PALdebuglog.o \
./Sources/PALthread.o \
./Sources/PALcritsec.o \
./Sources/PALprofiler.o \
./Sources/PALserializable.o \
./Sources/PALinet.o \
./Sources/PALnetwork.o \
./Sources/PALsocket.o \
./Sources/PALlocalhostUdpEvent.o \
./Sources/PALpollarray.o \
./Sources/PALrandom.o \
OBJS = $(OBJ_C) $(OBJ_CC)
SRCS = $(OBJ_C:.o=.c) $(OBJ_CC:.o=.cc)
debug: DEFINE += -DDEBUG
debug: BFLAGS = $(DEFINE) $(INCLUDE)
debug: CFLAGS = $(CCOPT_DEBUG) $(BFLAGS)
debug: $(OBJS)
ar crsu libpal_debug.a $(OBJS)
libpal.a: $(OBJS)
ar crsu libpal.a $(OBJS)
cleandeps:
$(RM) ./Sources/*.o .depend* core
clean: cleandeps
$(RM) ./libpal.a ./libpal_debug.a
$(RM) $(ALL)
And the resultant error is:
Makefile:34: *** missing separator. Stop.
You can find an explanation of this error in Appendix B Errors Generated by Make.
Every line in a recipe must begin with a tab character. The recipes starting with $(C++) and $(CC) near the top of your file do not seem to start with a tab character.
Additionally, the section
INCLUDE = \
-I./usr/include/sys
-I./Headers \
seems to be missing a backslash after sys and that same section (and many more) have superfluous empty lines.
Open your make file in vim rather than in editors like gedit. Every line in a recipe must begin with a tab character.
This answer is for other Make newbies such as myself who find this question from Googling and get stuck because they are modifying a large pre-existing Makefile, with no lines beginning with a space character. My problem occurred because a makefile in a subdirectory with spaces instead of tabs was getting called by a parent makefile, where I erroneously thought the problem existed.
Once I fixed the makefile in the subdirectory, everything worked like a charm.

make: -c: Command not found

First of all, I'm trying to get used to makefiles but yet I#m new with this. The following file is supposed to, first, compile all ./src/*.cpp files to ./src/*.o (where the filename survives) and afterwards complete compilation with simulation.cpp and linking the whole stuff together. Now, make returns the error message:
make: -c: Command not found
I have literally no clue how to proceed! Would the wildcard-construct even work in the way desired? Thanks a lot for your effort!
#basic stuff
TRUE = 1
FALSE = 0
SHELL := #!/bin/bash
# path names
SRCPATH = ./src/
CLEANPATH = ./res/ \
./crash/
# source files.
MAIN = simulation.cpp
OBJS = $(wildcard $(SRCPATH)*.o)
SRCS = $(wildcard $(SRCPATH)*.cpp)
INCLUDES = $(wildcard $(SRCPATH)*.h)
#GLOBAL MACROS PASSED TO PROGRAM!
MODEL_MRT = $(TRUE) #if true model used is MRT else SRT
PARALLEL = $(TRUE)
GRAVITY = $(TRUE)
# output file name
OUT = simulation
# C++ compiler flags (-g -O2 -Wall)
CXXFLAGS = -g -Wall -O -fopenmp
CXXDEFINES = -D MODEL=$(MODEL_MRT) -D PARALLEL=$(PARALLEL) -D GRAVITY=$(GRAVITY)
# compiler
CXX = g++
$(OUT) : $(OBJS)
$(CXX) $(CXXFLAGS) $(MAIN) $(OBJS) $(CXXDEFINES) -o $(OUT)
$(OBJS) : $(SRCS) $(INCLUDES)
$(CXX) $(CXXFLAGS) -c $(SRCS) -o $(OBJS)
clean : $(OUT)
rm $(OBJS)
rm $(CLEANPATH)/*.*
run : $(OUT) clean
./$(OUT)
.PHONY: clean run
You're tricking make with your SHELL variable, it sees is at empty as it is just a comment.
Change
SHELL := #!/bin/bash
to
SHELL := /bin/bash
This line:
SHELL := #!/bin/bash
is incorrect.
Your makefile should work perfectly well if you leave that line out altogether. If you do need something there, try
SHELL := /bin/bash

Resources