I have a Makefile as follows. make doesn't recompile the program when the linker script riscv32i.ld changes. What do I need to do to add a dependency on that file?
AS=riscv32-unknown-elf-as
CC=riscv32-unknown-elf-gcc
OC=riscv32-unknown-elf-objcopy
CFLAGS=-nostdlib -T riscv32i.ld
MAKEFLAGS += --silent
SOURCES=$(wildcard *.asm)
OBJ=$(patsubst %.asm,%.o, $(SOURCES))
ELF=$(patsubst %.asm,%.elf, $(SOURCES))
HEX=$(patsubst %.asm,%.hex, $(SOURCES))
.PHONY: all clean
all: $(HEX)
$(HEX): %.hex: %.elf
$(OC) -O binary $< $#
$(ELF): %.elf: %.o
$(CC) $(CFLAGS) -o $# $<
$(OBJ): %.o: %.asm
$(AS) -o $# $<
clean:
rm -f *.o *.elf *.hex
Okay I'm an idiot. Just adding riscv32i.ld as a prerequisite to $(ELF) works:
AS=riscv32-unknown-elf-as
CC=riscv32-unknown-elf-gcc
OC=riscv32-unknown-elf-objcopy
CFLAGS=-nostdlib -T riscv32i.ld
MAKEFLAGS += --silent
SOURCES=$(wildcard *.asm)
OBJ=$(patsubst %.asm,%.o, $(SOURCES))
ELF=$(patsubst %.asm,%.elf, $(SOURCES))
HEX=$(patsubst %.asm,%.hex, $(SOURCES))
.PHONY: all clean
all: $(HEX)
$(HEX): %.hex: %.elf
$(OC) -O binary $< $#
$(ELF): %.elf: %.o riscv32i.ld
$(CC) $(CFLAGS) -o $# $<
$(OBJ): %.o: %.asm
$(AS) -o $# $<
clean:
rm -f *.o *.elf *.hex
Related
I have 2 .c files that defined in the makefile:
SOURCES = main.c \
memory.c
and I want to build 2 .o files using 1 command "make compile-all" (and don't link them), but can't understand how to do this.
I could create var for objective files and add .PHONY command:
OBJS=$(SOURCES:.c=.o)
.PHONY: compile-all
But what should be written next?
I guess it should be something similar with this:
%.o: %.c $(INCLUDES)
$(CC) -c $< $(CFLAGS) -o $#
But there's no way I can succeed.
Thank you in advance!
BASENAME := main
TARGET := $(BASENAME).out
OBJS=$(SOURCES:.c=.o)
%.i: %.c
$(CC) -E $< $(CFLAGS) -o $#
%.asm: %.c
$(CC) -S $< $(CFLAGS) -o $#
%.o: %.c
$(CC) -c $< $(CFLAGS) -o $#
.PHONY: build
build:$(TARGET)
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(CFLAGS) $(PLATFORM_FLAGS) $(LDFLAGS) -o $#
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET) *.i *.asm $(BASENAME).map
.PHONY: compile-all
compile-all: $(OBJS)
make compile-all creates .o files from all .c files.
I have the following subdirectories:
libftprintf/
-Makefile(1)
-ft_printf.h
-ft_printf.c
-ft_printf_source1.c
-ft_printf_source2.c
-libft/
-Makefile(2)
-ft_atoi.c
-ft_itoa.c
-...
And what I want is to call makefile(2) (which gives me a libft.a file) from makefile(1) and add all under the same libftprintf.a file.
How do I go about to do this?
My makefile:
SRC_FILES:=$(wildcard *.c)
NAME=libftprintf.a
CC=gcc
CFLAGS=-Wall -Wextra -Werror
OBJ_DIR=obj
HDR=ft_printf.h
SRC_NAMES=$(patsubst %.c,%.o,$(SRC_FILES))
SRC_NAMES_O=$(addprefix $(OBJ_DIR)/, $(SRC_NAMES))
$(OBJ_DIR):
mkdir $#
%.o: %.c $(HDR) $(OBJ_DIR)
$(CC) $(CFLAGS) -c $< -o $(OBJ_DIR)/$#
$(NAME): $(OBJ_DIR) $(SRC_NAMES)
ar -rc $# $(SRC_NAMES_O)
ranlib $#
all: $(NAME)
bonus: all
clean:
rm -rf obj/
sclean: clean
fclean: clean
re: sclean all
.PHONY: all clean fclean re so
It is not possible to combine two static libraries together into a single static library, directly. It's just not something that's supported by the toolchain.
If you are determined to do it the only way is to write a little script that will extract every object file from one of the libraries using ar x and add each one into the other library with ar r.
I fixed it by copying the first library libft.a and renaming it libftprintf.a and then ar -rcs it with the object files.
My Makefile:
SRC_FILES:=$(wildcard *.c)
NAME=libftprintf.a
LIBFT=libft/libft.a
CC=gcc
CFLAGS=-Wall -Wextra -Werror
OBJ_DIR=obj
HDR=ft_printf.h
SRC_NAMES=$(patsubst %.c,%.o,$(SRC_FILES))
SRC_NAMES_O=$(addprefix $(OBJ_DIR)/, $(SRC_NAMES))
$(OBJ_DIR):
mkdir $#
%.o: %.c $(HDR) $(OBJ_DIR)
$(CC) $(CFLAGS) -c $< -o $(OBJ_DIR)/$#
$(LIBFT):
make -C libft
$(NAME): $(LIBFT) $(OBJ_DIR) $(SRC_NAMES)
cp libft/libft.a $#
ar -rcs $# $(SRC_NAMES_O)
all: $(NAME)
bonus: all
clean:
rm -rf obj/
make -C libft $#
fclean: clean
rm -f libftprintf.a
make -C libft $#
re: fclean all
.PHONY: all clean fclean re so
Executing make fails because it cannot find the previously defined rule in the make file. Also the "dir" rule only works if I use "make dir" but when I added it to the composed rule it lists the files in the working directory....
make test_tester
dir
base_types.c dynamic_array.c gists hashtable.c linked_list.c Makefile Makefile_OLD object.c object_table.c out.txt READ_THIS.txt sstring.c tester.c tests ttime.c
build/test_tester.o
make: build/test_tester.o: Command not found
Makefile:7: recipe for target 'test_tester' failed
make: *** [test_tester] Error 127
CC=gcc
CFLAGS=-Wall -I ../include
TEST_DIR=tests
BUILD_DIR=build
test_tester:
dir
$(BUILD_DIR)/test_tester.o
$(BUILD_DIR)/tester.o
$(BUILD_DIR)/base_types.o
$(BUILD_DIR)/object.o
$(BUILD_DIR)/sstring.o
$(CC) $(CFLAGS) $(BUILD_DIR)/test_tester.o $(BUILD_DIR)/tester.o $(BUILD_DIR)/base_types.o \
$(BUILD_DIR)/object.o $(BUILD_DIR)/sstring.o
$(BUILD_DIR)/test_tester.o:
$(CC) $(CFLAGS) -c $(TEST_DIR)/test_tester.c -o $#
$(BUILD_DIR)/tester.o: tester.c
$(CC) $(CFLAGS) -c tester.c -o $#
$(BUILD_DIR)/base_types.o: base_types.c
$(CC) $(CFLAGS) -c base_types.c -o $#
$(BUILD_DIR)/object.o: object.c
$(CC) $(CFLAGS) -c object.c -o $#
$(BUILD_DIR)/sstring.o: sstring.c
$(CC) $(CFLAGS) -c sstring.c -o $#
dir: mkdir -p $(BUILD_DIR)
.PHONY: clean
clean:
rm -f $(BUILD_DIR)/*.o
I figured it out thanks.
CC=gcc
CFLAGS=-Wall -I ../include
TEST_DIR=tests
BUILD_DIR=build
test_tester: dir test_tester.o tester.o base_types.o object.o sstring.o
$(CC) $(CFLAGS) $(BUILD_DIR)/test_tester.o $(BUILD_DIR)/tester.o $(BUILD_DIR)/base_types.o $(BUILD_DIR)/object.o $(BUILD_DIR)/sstring.o -o $#
test_tester.o:
$(CC) $(CFLAGS) -c $(TEST_DIR)/test_tester.c -o $(BUILD_DIR)/$#
tester.o: tester.c
$(CC) $(CFLAGS) -c tester.c -o $(BUILD_DIR)/$#
base_types.o: base_types.c
$(CC) $(CFLAGS) -c base_types.c -o $(BUILD_DIR)/$#
object.o: object.c
$(CC) $(CFLAGS) -c object.c -o $(BUILD_DIR)/$#
sstring.o: sstring.c
$(CC) $(CFLAGS) -c sstring.c -o $(BUILD_DIR)/$#
dir:
mkdir -p $(BUILD_DIR)
.PHONY: clean
clean:
rm -fr $(BUILD_DIR)
I've the following situation:
SOURCES=home/main.cpp modelChecking/Configuracao.cpp modelChecking/Estado.cpp modelChecking/Formula.cpp modelChecking/ModelChecking.cpp lib/VisitTree.cpp
SUFIX=$(SOURCES:.cpp=.o)
OBJECTS=$(SUFIX)
all: refiner
refiner: $(OBJECTS)
$(CC) $^ -o refiner
home/main.o: home/main.cpp
$(CC) $(CFLAGS) $< -o $#
modelChecking/Configuracao.o: modelChecking/Configuracao.cpp
$(CC) $(CFLAGS) $< -o $#
modelChecking/Estado.o: modelChecking/Estado.cpp
$(CC) $(CFLAGS) $< -o $#
...
...and so on.
As you can see, I have different directories to compile my executable.
Now, I want to put every file .o in the bin/ folder and the variable OBJECT must replace the every parent directory, and I tried different ways:
OBJECTS=$(SUFIX:%/ = bin/)
OBJECTS=$(subst %/,bin/,$(SUFIX))
OBJECTS=$(patsubst %/,bin/,$(SUFIX))
When I use something like this $(subst home/,bin/,$(SUFIX)) it works, because I type the substring "home/", but I need of a regular expression to replace all directories.
And I'll need to change the target too, perhaps the code below will works:
%.o: %.cpp
$(CC) $(CFLAGS) $< -o $#
... But I prefer every target separate
You are looking for SUFIX=$(addprefix bin/,$(notdir $(SOURCES:.cpp=.o)))
The Makefile will look like:
SOURCES=home/main.cpp modelChecking/Configuracao.cpp
SUFIX=$(addprefix bin/,$(notdir $(SOURCES:.cpp=.o)))
OBJECTS=$(SUFIX)
all: refiner
refiner: $(OBJECTS)
$(CC) $^ -o refiner
bin/main.o: home/main.cpp
$(CC) $(CFLAGS) -c $< -o $#
bin/Configuracao.o: modelChecking/Configuracao.cpp
$(CC) $(CFLAGS) -c $< -o $#
However I suggest to use SUBDIRS instead. Create to Makefiles
Makefile
SUBDIRS = bin
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $#
bin/Makefile
SOURCES=../home/main.cpp ../modelChecking/Configuracao.cpp
SUFIX=$(addprefix bin/,$(notdir $(SOURCES:.cpp=.o)))
OBJECTS=$(SUFIX)
all: refiner
refiner: $(OBJECTS)
$(CC) $^ -o refiner
main.o: ../home/main.cpp
$(CC) $(CFLAGS) -c $< -o $#
Configuracao.o: ../modelChecking/Configuracao.cpp
$(CC) $(CFLAGS) -c $< -o $#
This way you will not have to worry about object prefix.
I want to make a modular makefile with a PATH parameter but I can't figure out how.
This is what I had before:
CC=
CFLAGS=-c -stack-protect
LDFLAGS=
SOURCES=
SSOURCES=
OBJECTS=$(SOURCES:.cpp=.o)
SOBJECTS=$(SSOURCES:.s=.o)
DEBUGFLAGS=-g -DDEBUG
EXECUTABLE=
all: CC += -DNDEBUG
all: $(SOURCES) $(SSOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS) $(SOBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(SOBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
.s.o:
$(CC) $(CFLAGS) $< -o $#
debug: CFLAGS += $(DEBUGFLAGS)
debug: $(SOURCES) $(SSOURCES) $(LDFLAGS) $(EXECUTABLE)
$(CC) $(LDFLAGS) $(OBJECTS) $(SOBJECTS) -o $(EXECUTABLE)
clean:
rm -rf *o $(OBJECTS) $(SOBJECTS)
And this is what I'm trying to do more or less:
PATH=
CC=
CFLAGS=-c -stack-protect
LDFLAGS=
SOURCES=./src1 ./src1
SSOURCES=./src1 ./src2
FSOURCES=$(SOURCES:./=$(PATH))
FSSOURCES=$(SSOURCES:./=$(PATH))
OBJECTS=$(SOURCES:.cpp=.o)
SOBJECTS=$(SSOURCES:.s=.o)
DEBUGFLAGS=-g -DDEBUG
EXECUTABLE=
all: CC += -DNDEBUG
all: $(FSOURCES) $(FSSOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS) $(SOBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(SOBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
.s.o:
$(CC) $(CFLAGS) $< -o $#
debug: CFLAGS += $(DEBUGFLAGS)
debug: $(FSOURCES) $(FSSOURCES) $(LDFLAGS) $(EXECUTABLE)
$(CC) $(LDFLAGS) $(OBJECTS) $(SOBJECTS) -o $(EXECUTABLE)
clean:
rm -rf *o $(OBJECTS) $(SOBJECTS)
How can I make this work?
I am assuming that the files that the files you want to make .so are in the folder src2 and the files that you want to build and create and executable are in the in the folder src1.
VPATH = src1:src2:objects:include:libs
CFLAGS= -I ./include -Wall -g -stack-protect
LDFLAGS = -lstdc++
# You can append more libs as required.
CC = gcc
target: $(patsubst ./src1/%.c,./objects/%.o,$(wildcard ./src1/*.c)) ./libs/libmylib.so
$(CC) $(patsubst ./src/%.c,./obj_dbg/%.o,$(wildcard ./src/*.c)) $(LDFLAGS) -L ./libs -lmylib -o target
./objects/%.o: ./src/%.c ./include/*.h
#mkdir -p ./objects
$(CC) $(CFLAGS) -c $< -o $#
./libs/libmylib.so: ./src2/%.c ./include/*.h
#mkdir -p ./libs
$(CC) $(CFLAGS) -c $< -o $#
For makefile tutorial, you can check the following link.
http://www.tune2wizard.com/linux-makefiles/