I want to create a static library using Makefile in linux.
I want to know if this makefile true or not ?
I'm open to other ideas. Thanks all.
NAME= libamqp.a
CC := gcc
CFLAGS := -c -Wall -g
SRCDIR := src
OBJDIR := obj
#definition des fichiers headers
INCLUDES := -I/usr/local/include/ -I/home/tvi/projets/RabbitMQ/libamqp/dlo -I/home/tvi/projets/RabbitMQ/rabbitmq-c/librabbitmq
#definition des librairies
LFLAGS := -L/usr/local/lib64
LDFLAGS :=
LIBS := -L. -lrabbitmq
SRCS_RAW := amqp_connexion.c amqp_consommateur.c amqp_deconnexion.c amqp_producteur.c amqp_outils.c
SRCS := $(addprefix $(SRCDIR)/,$(SRCS_RAW))
OBJS := $(addprefix $(OBJDIR)/,$(SRCS_RAW:.c=.o))
.PHONY: all
all: $(NAME)
#echo "$(MAKE) : Tout est généré"
$(NAME):$(OBJS)
$(CC) $(CFLAGS) $(SRCS) $(INCLUDES) $(LFLAGS) $(LIBS)
ar rcs $(NAME) $(OBJS)
ranlib $(NAME)
$(OBJS): $(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $# $(INCLUDES)
.PHONY: clean
clean:
$(RM) *~ $(NAME)
$(RM) -r $(OBJDIR)
NAME= libamqp.a
CC := gcc
CFLAGS := -Wall -g
SRCDIR := src
OBJDIR := obj
#definition des fichiers headers
INCLUDES := -I/usr/local/include/ -I/home/tvi/projets/RabbitMQ/libamqp/dlo -I/home/tvi/projets/RabbitMQ/rabbitmq-c/librabbitmq
#definition des librairies
LFLAGS := -L/usr/local/lib64
LDFLAGS :=
LIBS := -L. -lrabbitmq
SRCS_RAW := amqp_connexion.c amqp_consommateur.c amqp_deconnexion.c amqp_producteur.c amqp_outils.c
SRCS := $(addprefix $(SRCDIR)/,$(SRCS_RAW))
OBJS := $(addprefix $(OBJDIR)/,$(SRCS_RAW:.c=.o))
#$(info DEBUG: SRCS=$(SRCS))
#$(info DEBUG: OBJS=$(OBJS))
#$(info DEBUG: EXEC=$(EXEC))
.PHONY: all
all: $(NAME)
#echo "$(MAKE) : Tout est genere"
$(NAME):$(OBJS)
ar rcs $(NAME) $(OBJS)
ranlib $(NAME)
#règle pour créer un répertoire d'objets s'il n'existe pas
$(OBJDIR):
mkdir $(OBJDIR)
#définir une règle implicite pour créer des objets dans leur propre répertoire
#(note - ordre uniquement la dépendance sur le répertoire d'objets)
#$< :premier_dependance $#:cible
$(OBJS): $(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
.PHONY: clean
clean:
$(RM) *~ $(NAME)
$(RM) -r $(OBJDIR)
Related
Hi I know there is some other posts with the same title, but they are not in the same context. So: I have a library named mlx and the library file is named libmlx.dylib: when I try to compile it with a simple main using gcc main.c libmlx.dylib it compiles well and the lib is working, but when I try to compile it with my project using my makefile the compilation doesn't throw any error but when I launch the program I get this error message:
dyld: Library not loaded: libmlx.dylib
Referenced from: /Users/leo/Documents/42-cursus/so_long/./so_long
Reason: image not found
[1] 8313 abort ./so_long
Here is my makefile:
SHELL = /bin/sh
NAME = so_long
.SUFFIXES = .c .o .h .dylib
SRCDIR = src
INCDIR = inc
LIBDIR = lib
OBJDIR = .obj
SRC = $(addsuffix $(word 1, $(.SUFFIXES)),\
$(addprefix exception/,\
exception\
bad_alloc\
invalid_arguments\
invalid_map\
runtime_error)\
$(addprefix parsing/,\
get_map)\
$(addprefix rendering/,\
render_map)\
$(addprefix utils/,\
init_image\
make_color)\
$(addprefix cleaning/,\
mlx_clear)\
$(addprefix get_next_line/,\
get_next_line\
get_next_line_utils)\
main)
INC = $(addsuffix $(word 3, $(.SUFFIXES)),\
get_next_line\
mlx\
exception\
so_long)
LIB = mlx\
ft
OBJ = $(SRC:$(word 1, $(.SUFFIXES))=$(word 2, $(.SUFFIXES)))
CC = gcc
CFLAGS = -Wall -Wextra -Werror -I $(INCDIR)
LCFLAGS = $(addprefix -L, $(LIBDIR)) $(addprefix -l, $(lib))
#### COLORS ####
KNRM = \x1B[0m
KRED = \x1B[31m
KGRN = \x1B[32m
KYEL = \x1B[33m
KBLU = \x1B[34m
KMAG = \x1B[35m
KCYN = \x1B[36m
KWHT = \x1B[37m
######################
all: $(OBJDIR) $(NAME)
#printf "$(KGRN)\`$(NAME)\` is up to date.\n$(KNRM)"
$(OBJDIR):
#printf "$(KYEL)➤ "
mkdir -p $#/exception $#/parsing $#/rendering $#/utils $#/cleaning $#/get_next_line
#printf "$(KNRM)"
$(NAME): $(addprefix $(OBJDIR)/, $(OBJ))
#printf "$(KCYN)[ Linking ]\n➤ "
$(CC) $(CFLAGS) $^ -o $# $(LCFLAGS)
#printf "$(KNRM)"
$(OBJDIR)/%$(word 2, $(.SUFFIXES)): $(SRCDIR)/%$(word 1, $(.SUFFIXES)) $(addprefix $(INCDIR)/, $(INC))
#printf "$(KMAG)[ Compiling ]\n➤ "
$(CC) $(CFLAGS) -c $< -o $#
#printf "$(KNRM)"
clean:
#printf "$(KRED)➤ "
rm -rf $(OBJDIR)
#printf "$(KNRM)"
fclean: clean
#printf "$(KRED)➤ "
rm -f $(NAME)
#printf "$(KNRM)"
re: fclean all
I'm linking it with the flags -L $(LIBDIR) -lmlx. What did I do wrong ?
I found that for dynamic libraries you need to have the .dylib in the same directory as your target, I let the post in case some people face the same problem.
I got a project hierarchy that looks like this:
+Makefile
+---src
| main.c
| ...
| +---block
| | air.c
| | ...
| |
| +---entity
| | esc.c
| | esc.h
| | ...
| |
| \---world
| \---gen
| noise.c
| ...
| xyz.c
| ...
\---obj
main.o
air.o
esc.o
noise.o
xyz.o
...
I want to compile all the .c files in the hierarchy into one obj folder using make.
So far I got:
UNAME_S = $(shell uname -s)
CC = clang
CFLAGS = -std=c11 -O3 -g -Wall -Wextra -Wpedantic -Wstrict-aliasing
CFLAGS += -Wno-pointer-arith -Wno-newline-eof -Wno-unused-parameter -Wno-gnu-statement-expression
CFLAGS += -Wno-gnu-compound-literal-initializer -Wno-gnu-zero-variadic-macro-arguments
CFLAGS += -Ilib/cglm/include -Ilib/glad/include -Ilib/glfw/include -Ilib/stb -Ilib/noise -fbracket-depth=1024
LDFLAGS = lib/glad/src/glad.o lib/cglm/libcglm.a lib/glfw/src/libglfw3.a lib/noise/libnoise.a -lm
# GLFW required frameworks on OSX
ifeq ($(UNAME_S), Darwin)
LDFLAGS += -framework OpenGL -framework IOKit -framework CoreVideo -framework Cocoa
endif
ifeq ($(UNAME_S), Linux)
LDFLAGS += -ldl -lpthread
endif
OBJ_DIR = obj
SRC = $(wildcard src/**/*.c) $(wildcard src/*.c) $(wildcard src/**/**/*.c) $(wildcard src/**/**/**/*.c)
OBJ = $(addprefix $(OBJ_DIR)/,$(addsuffix .o,$(notdir $(basename $(SRC)))))
SRC_DIRS = $(sort $(dir $(SRC)))
BIN = bin
.PHONY: all clean
all: dirs libs game
libs:
cd lib/cglm && cmake . -DCGLM_STATIC=ON && make
cd lib/glad && $(CC) -o src/glad.o -Iinclude -c src/glad.c
cd lib/glfw && cmake . && make
cd lib/noise && make
dirs:
mkdir -p ./$(BIN) ./$(OBJ_DIR)
run: all
$(BIN)/game
game: $(OBJ)
$(CC) -o $(BIN)/game $^ $(LDFLAGS)
$(OBJ_DIR)/%.o: src/%.c
$(CC) -o $# -c $< $(CFLAGS)
$(OBJ_DIR)/%.o: src/block/%.c
$(CC) -o $# -c $< $(CFLAGS)
$(OBJ_DIR)/%.o: src/entity/%.c
$(CC) -o $# -c $< $(CFLAGS)
$(OBJ_DIR)/%.o: src/gfx/%.c
$(CC) -o $# -c $< $(CFLAGS)
$(OBJ_DIR)/%.o: src/ui/%.c
$(CC) -o $# -c $< $(CFLAGS)
$(OBJ_DIR)/%.o: src/util/%.c
$(CC) -o $# -c $< $(CFLAGS)
$(OBJ_DIR)/%.o: src/world/%.c
$(CC) -o $# -c $< $(CFLAGS)
$(OBJ_DIR)/%.o: src/world/gen/%.c
$(CC) -o $# -c $< $(CFLAGS)
clean:
rm -rf $(BIN) $(OBJ_DIR)
Is there any way to get this done in a more efficient way? Especially the $(OBJ_DIR)/%.o cases?
Variable $(SRC_DIRS) stores all src folders
Variable $(SRC) stores all .c files with their paths
Variable $(OBJ) stores all .o file paths and names
The best way to do this is using VPATH.
For example:
SRC := $(wildcard src/*/*.c) $(wildcard src/*.c) $(wildcard src/*/*/*.c) $(wildcard src/*/*/*/*.c)
OBJ := $(addprefix $(OBJ_DIR)/,$(addsuffix .o,$(notdir $(basename $(SRC)))))
SRC_DIRS := $(sort $(dir $(SRC)))
VPATH := $(SRC_DIRS)
...
$(OBJ_DIR)/%.o: %.c
$(CC) -o $# -c $< $(CFLAGS)
You just need the one pattern rule.
I have a C-application that i'm trying to build with a makefile. When I call make I get:
Compiling file: nrf_drv_rtc.c
arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -mabi=aapcs --std=gnu99 -Wall -O0 -g3 -mfloat-abi=soft -ffunction-sections -fdata-sections -fno-strict-aliasing -c -o build/nrf_drv_rtc.o nrf51_sdk/drivers_nrf/rtc/nrf_drv_rtc.c
"C:/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q1/bin/arm-none-eabi-gcc" -mcpu=cortex-m0 -mthumb -mabi=aapcs --std=gnu99 -Wall -O0 -g3 -mfloat-abi=soft -ffunction-sections -fdata-sections -fno-strict-aliasing -c -o build/nrf_drv_rtc.o nrf51_sdk/drivers_nrf/rtc/nrf_drv_rtc.c
The system cannot find the path specified.
make[1]: *** [build/nrf_drv_rtc.o] Error 1
And true enough no "build/nrf_drv_rtc.o" file is build. Strange thing is that if i copy the line:
arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -mabi=aapcs --std=gnu99 -Wall -O0 -g3 -mfloat-abi=soft -ffunction-sections -fdata-sections -fno-strict-aliasing -c -o build/nrf_drv_rtc.o nrf51_sdk/drivers_nrf/rtc/nrf_drv_rtc.c
to cmd and runs it, it compiles fine and generate "build/nrf_drv_rtc.o"?
Here's my makefile:
PROJECT_NAME := ble_app_hrs_s110_pca10028
export OUTPUT_FILENAME
#MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
MAKEFILE_NAME := $(MAKEFILE_LIST)
MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) )
TEMPLATE_PATH = nrf51_sdk/toolchain/gcc
ifeq ($(OS),Windows_NT)
include $(TEMPLATE_PATH)/Makefile.windows
else
include $(TEMPLATE_PATH)/Makefile.posix
endif
MK := mkdir
RM := rm -rf
#echo suspend
ifeq ("$(VERBOSE)","1")
NO_ECHO :=
else
NO_ECHO := #
endif
# Toolchain commands
CC := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc"
AS := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as"
AR := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar" -r
LD := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld"
NM := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm"
OBJDUMP := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump"
OBJCOPY := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy"
SIZE := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-size"
#function for removing duplicates in a list
remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1))))
#source common to all targets
C_SOURCE_FILES += \
nrf51_sdk/drivers_nrf/rtc/nrf_drv_rtc.c \
Drivers/NRF51_BLEDriver.c \
(..... a lot more files ....)
#assembly files common to all targets
ASM_SOURCE_FILES = nrf51_sdk/toolchain/gcc/gcc_startup_nrf51.s
#includes common to all targets
INC_PATHS = -I Application/
(..... a lot more include paths.......)
OBJECT_DIRECTORY = _build
LISTING_DIRECTORY =$(OBJECT_DIRECTORY)
OUTPUT_BINARY_DIRECTORY =$(OBJECT_DIRECTORY)
# Sorting removes duplicates
BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LISTING_DIRECTORY) )
#flags common to all targets
CFLAGS = -DSOFTDEVICE_PRESENT
CFLAGS += -DNRF51
CFLAGS += -DS110
CFLAGS += -DBOARD_PCA10028
CFLAGS += -DBLE_STACK_SUPPORT_REQD
CFLAGS += -mcpu=cortex-m0
CFLAGS += -mthumb -mabi=aapcs --std=gnu99
CFLAGS += -Wall -O0 -g3
CFLAGS += -mfloat-abi=soft
# keep every function in separate section. This will allow linker to dump unused functions
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
#CFLAGS += -flto -fno-builtin
# keep every function in separate section. This will allow linker to dump unused functions
LDFLAGS += -Xlinker -Map=$(LISTING_DIRECTORY)/$(OUTPUT_FILENAME).map
LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
LDFLAGS += -mcpu=cortex-m0
# let linker to dump unused sections
LDFLAGS += -Wl,--gc-sections
# use newlib in nano version
LDFLAGS += --specs=nano.specs -lc -lnosys
# Assembler flags
ASMFLAGS += -x assembler-with-cpp
ASMFLAGS += -DSOFTDEVICE_PRESENT
ASMFLAGS += -DNRF51
ASMFLAGS += -DS110
ASMFLAGS += -DBOARD_PCA10028
ASMFLAGS += -DBLE_STACK_SUPPORT_REQD
#default target - first one defined
#default: clean nrf51422_xxac_s110
#building all targets
all: #clean
#$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e cleanobj
$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e nrf51422_xxac_s110
#target for printing all targets
help:
#echo following targets are available:
#echo nrf51422_xxac_s110
#echo flash_softdevice
C_SOURCE_FILE_NAMES = $(notdir $(C_SOURCE_FILES))
C_PATHS = $(call remduplicates, $(dir $(C_SOURCE_FILES) ) )
C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILE_NAMES:.c=.o) )
ASM_SOURCE_FILE_NAMES = $(notdir $(ASM_SOURCE_FILES))
ASM_PATHS = $(call remduplicates, $(dir $(ASM_SOURCE_FILES) ))
ASM_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(ASM_SOURCE_FILE_NAMES:.s=.o) )
vpath %.c $(C_PATHS)
vpath %.s $(ASM_PATHS)
OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS)
nrf51422_xxac_s110: OUTPUT_FILENAME := nrf51422_xxac_s110
nrf51422_xxac_s110: LINKER_SCRIPT=ble_app_hrs_gcc_nrf51.ld
nrf51422_xxac_s110: $(BUILD_DIRECTORIES) $(OBJECTS)
#echo Linking target: $(OUTPUT_FILENAME).out
$(NO_ECHO)$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e finalize
## Create build directories
$(BUILD_DIRECTORIES):
echo $(MAKEFILE_NAME)
$(MK) $#
# Create objects from C SRC files
$(OBJECT_DIRECTORY)/%.o: %.c
#echo Compiling file: $(notdir $<)
#echo arm-none-eabi-gcc $(CFLAGS) $(INC_PATHS) -c -o $# $<
$(NO_ECHO)$(CC) $(CFLAGS) $(INC_PATHS) -c -o $# $<
# Assemble files
$(OBJECT_DIRECTORY)/%.o: %.s
#echo Compiling file: $(notdir $<)
$(NO_ECHO)$(CC) $(ASMFLAGS) $(INC_PATHS) -c -o $# $<
# Link
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out: $(BUILD_DIRECTORIES) $(OBJECTS)
#echo Linking target: $(OUTPUT_FILENAME).out
$(NO_ECHO)$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
## Create binary .bin file from the .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
#echo Preparing: $(OUTPUT_FILENAME).bin
$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin
## Create binary .hex file from the .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
#echo Preparing: $(OUTPUT_FILENAME).hex
$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
finalize: genbin genhex echosize
genbin:
#echo Preparing: $(OUTPUT_FILENAME).bin
$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin
## Create binary .hex file from the .out file
genhex:
#echo Preparing: $(OUTPUT_FILENAME).hex
$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
echosize:
-#echo ""
$(NO_ECHO)$(SIZE) $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
-#echo ""
clean:
$(RM) $(BUILD_DIRECTORIES)
cleanobj:
$(RM) $(BUILD_DIRECTORIES)/*.o
flash: $(MAKECMDGOALS)
#echo Flashing: $(OUTPUT_BINARY_DIRECTORY)/$<.hex
nrfjprog --reset --program $(OUTPUT_BINARY_DIRECTORY)/$<.hex)
## Flash softdevice
flash_softdevice:
#echo Flashing: s110_softdevice.hex
nrfjprog --reset --program nrf51_sdk/softdevice/s110/hex/s110_softdevice.hex
Turns out, that the include: include $(TEMPLATE_PATH)/Makefile.windows defined the GNU_INSTALL_ROOT variable as a compiler version that wasn't installed on my computer. So I corrected it, and everything works like a charm .
I have below file list:
fd1/foo.c
fd2/foo.c
fd2/bar.c
fd2/bar.h
I want to compile fd1/foo.c and fd2/bar.c. fd2/foo.c is an excluded one. If I use vapth to select all source files, the fd2/foo.c will be compiled. So I want to specify the source list:
SRC_C = fd1/foo.c fd2/bar.c
Since I can't use vpath, so I can only compile SRC_C something like this:
SRC_O = $(patsubst %.c,%.o,$(SRC_C))
SRC_C_LIST = $(notdir $(SRC_C))
OBJ_LIST = $(patsubst %.c,%.o,$(SRC_C_LIST) )
.PHONY: all
all: $(OBJ_LIST)
ar rvs foobar.a $(OBJ_LIST)
$(SRC_O): %.o : %.c
gcc -c $< -I inc/ -MM -MF $(patsubst .o,.d,$(notdir $#)) -o $(notdir $#)
But I also want add dependency rules. But the dependency file seems only contain object target without original folder names:
foo.o : src/foo.c inc/bar.h
How do I to use dependency file in this case? Thanks.
Solutions
Per suggestion from Joachim, I modify my solution as below. Seems work:
SRC_C = fd1/foo.c fd2/bar.c
SRC_O = $(patsubst %.c,%.o,$(SRC_C))
SRC_C_LIST = $(notdir $(SRC_C))
OBJ_LIST = $(patsubst %.c,%.o,$(SRC_C_LIST) )
SRC_D_LIST = $(patsubst %.o,%.d,$(OBJ_LIST))
.PHONY:all
all: $(SRC_O)
ar rvs foobar.a $(OBJ_LIST)
$(SRC_O): %.o : %.c
arm-none-eabi-gcc -c $< -I inc/ -o $# -MM -MT $# -MF $(notdir $(patsubst %.o,%.d,$#))
-include $(SRC_D_LIST)
Using implicit rules, if you do not mind having the .o and .d files along the corresponding .c files:
LIB := foobar.a
SRC := fd1/foo.c fd2/bar.c
OBJ := $(SRC:.c=.o)
DEP := $(OBJ:.o=.d)
CC := arm-none-eabi-gcc
ARFLAGS := rvs
CPPFLAGS := -MMD -MP -I inc
.PHONY: all
.PRECIOUS: $(OBJ)
all: $(LIB)
$(LIB): $(LIB)($(OBJ))
-include $(DEP)
# Arquitectura
CC := arm-none-eabi-
# Compiladores
GCC :=$(CC)gcc
AS :=$(CC)as
LIBC :=$(CC)ar
# Linker
LINKER :=$(CC)ld
# Flags compilação
FLAGDEBUG :=-g
CFLAGS :=-c -mapcs #-Wall
CDEPEND :=-MM -MF
LIBFLAG := rcs
LDSCRIPT := -T
LDLIBDIR := -L
LDLIBLIBS := -l
# $# -> nome do alvo .. $^/S? lista de dependencias .. $* contêm o valor de % .. $< contêm a primeira dependencia
# Pastas
DEPDIR := Depends/
SOURCEDIR := Source/
SOURCECDIR :=$(SOURCEDIR)C/
SOURCEADIR :=$(SOURCEDIR)Assembly/
LIBDIR := Library/
HEADDIR := Header/
OBJDIR := Object/
# Dependencias
SOURCEC := $(wildcard $(SOURCECDIR)*.c)
SOURCEA := $(wildcard $(SOURCEADIR)*.S)
OBJC :=$(patsubst $(SOURCECDIR)%.c,%.o,$(SOURCEC))
OBJA :=$(patsubst $(SOURCEADIR)%.S,%.o,$(SOURCEA))
HEADER :=$(wildcard $(HEADDIR)*.h)
LIBL = $(wildcard $(LIBDIR)*.a)
#LIBL = $(wildcard $(LIBDIR)lib*.a)
DEPEND :=$(patsubst %.o,$(DEPDIR)%.d,$(OBJC))
SCRIPT := $(wildcard *.ld)
LIB =
# Ficheiros de output
FICHDEBUG := Teste.axf
FICHRELEASE := Release.axf
debug: $(FICHDEBUG)
# Executável para debug
$(FICHDEBUG):$(OBJA) $(OBJC)
#echo A efectuar a linkagem dos módulos para gerar o executável $#
#$(LINKER) $(OBJA) $(OBJC) $(LDSCRIPT) $(SCRIPT) -o $#
# Compilar ficheiros .S e .c
%.o:$(SOURCEADIR)%.S
#echo A compilar $# a partir de $*.S
#$(AS) $(FLAGDEBUG) $< -o $#
%.o:$(SOURCECDIR)%.c
#echo A compilar $# a partir de $*.c
$(GCC) $(CDEPEND) $(patsubst %.o,$(DEPDIR)%.d,$#) $<
$(GCC) $(FLAGDEBUG) $(CFLAGS) $< -o $#
-include $(DEPEND)
release: $(FICHRELEASE)
$(FICHRELEASE): $(OBJA) $(OBJC)
#echo A efectuar a linkagem dos módulos para gerar o executável $#
#$(LINKER) $(OBJA) main.o $(LDSCRIPT) $(SCRIPT) -o $# $(LDLIBDIR) $(LIBDIR) $(LDLIBLIBS)
# Gerar bibliotecas necessárias
gerarLib:$(HEADER)
#echo $(HEADER)
$(HEADDIR)%.h: %.o
#echo $# $*
#$(eval LIB = $(patsubst $(HEADDIR)%.h,$(LIBDIR)lib%.a,$#))
$(LIBC) $(LIBFLAG) $(LIB) $(patsubst $(LIBDIR)lib%.a,%.o,$(LIB))
.PHONY: clean
clean:
# rm -rf $(DEPDIR)*.d $(SOURCEDIR)*/*~ *~ *.o $(LIBDIR)*.a *.axf *.o
So heres the makefile I'm using. As it is it generates the code as its supposed ant it updates correctly when any file changes(.h or .c), the issue is the dependencies generated do not have the proper object path set(I've read its a bug in gcc when it writes to file the dependencies) so I thought I'd make a script that simply adds the path to it and it would work and I'd be able to put my object files where they belong(Object folder) however every time I try to run make after the initial compilation(which works fine btw) it gives me an erro saying one of the header files doesn't exist(which is untrue since the file is there and I can access it).
Anyone have an idea of whats happening?(to change between the "modes" I simply write $(OBJDIR) before every %.o and *.o)
This rule looks suspicious:
$(HEADDIR)%.h: %.o
#echo $# $*
#$(eval LIB = $(patsubst $(HEADDIR)%.h,$(LIBDIR)lib%.a,$#))
$(LIBC) $(LIBFLAG) $(LIB) $(patsubst $(LIBDIR)lib%.a,%.o,$(LIB))
It claims to be creating .h files from .o files, but that seems unlikely, given the rules.