Automake: embedding text files in binary target - automake

I need to embed several text files in a binary. It's currently done with two lines added in configure.in script that do "clean" and perform objcopy to the $target.o files. Don't ask WHY it's required, in this app, it just is.
What I want to do is write some automake (Makefile.am) difinitions that would list those text files as source and tell make to objcopy them into *.o files I need to link with the final target. I could also add them to CLEANFILES, which I want.
Now, I know I say final_LDADD, but I can't find the way to tell automake/configure to do that trick.
Help...

Something like:
libxxx.a : text1.o text2.o
$(AR) cru $# $^
text1.o : text1.txt
$(OBJCOPY) $< $#
text2.o : text2.txt
$(OBJCOPY) $< $#
...
final_LDADD = libxxx.a
...
CLEANFILES += libxxx.a text1.o text2.o

Slightly modified ldav1s's solution:
object_files = file0.o file1.o file2.o ... fileN.o
all:
for SQL in $$(echo ${object_files} | sed -r 's~\.o\b~~g'); do \
$(OBJCOPY) $$SQL $$SQL.o; \
done;
CLEANFILES = ${object_files}

Related

Is it possible to create a target that repeats an action for different files?

I'm trying to build a Makefile that simplifies compilation for a C assignment. The Makefile works fine for now, however, I would like to add a new target that executes a previous target and creates files.
The objective is the following:
Compile a given program (figures.c)
Execute it (this creates a bunch of .gv files)
Transform every .gv file to a .pdf file
I know how to transform a single file (I have the command), but can't seem to figure out how to loop through every file, without typing them all out.
I've already tried doing a different type of target, but does not work (see commented target)
# COMPILATION
CC=gcc
CFLAGS=-Wall -ansi -pedantic
# DOSSIERS
SOURCEDOC=sourcedoc
DOC=doc
SRC=src
INC=inc
OBJ=build
FIGS=images
FILES=$(wildcard $(FIGS)/*.gv)
.PHONY: clean doc archive author all
.SILENT : clean
# Targets
all : clean test images
test : $(OBJ)/Test_arbre.o $(OBJ)/aux.o $(OBJ)/Affichage.o $(OBJ)/ArbreBinaire.o $(OBJ)/arbres.o
$(CC) $^ -o $# $(CFLAGS)
figures : $(OBJ)/figures.o $(OBJ)/Affichage.o $(OBJ)/ArbreBinaire.o $(OBJ)/aux.o $(OBJ)/arbres.o
$(CC) $^ -o $# $(CFLAGS)
%.pdf: $(FIGS)/%.gv
dot -Tpdf -o $(FIGS)/$# $^
#$(FILES): $(FIGS)/%.pdf : $(FIGS)/%.gv
# dot -Tpdf -o $# $^
images : figures $(FILES)
#=========== Objets ===========
$(OBJ)/arbres.o : $(INC)/arbres.h $(INC)/aux.h $(INC)/Affichage.h $(INC)/ArbreBinaire.h
$(OBJ)/Affichage.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h
$(OBJ)/exemple*_arbre.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h
$(OBJ)/aux.o : $(INC)/aux.h
$(OBJ)/figures.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h $(INC)/arbres.h
$(OBJ)/Test_arbre.o : $(INC)/arbres.h $(INC)/ArbreBinaire.h $(INC)/Affichage.h
# Dummy rule
$(OBJ)/%.o : $(SRC)/%.c
#mkdir -p $(#D)
#$(CC) $< $(CFLAGS) -I $(INC)/ -c -o $#
# Miscellaneous
clean:
rm -f *~ */*~
rm -rf __pycache__ src/__pycache__
rm -rf $(DOC)
rm -f $(PROJECT)_$(AUTHOR12)_$(AUTHOR22).zip
rm -f conf.py-e
rm -rf $(OBJ)
rm -f $(FIGS)/*.pdf $(FIGS)/*.gv
rm -f test
The current Makefile works fine on all other commands than images.
If any of you could help, it would mean a lot!
Your definition of FILES should map the *.gv files to the corresponding *.pdf files;
FILES=$(patsubst %.gv,%.pdf,$(wildcard $(FIGS)/*.gv))
The rule which says how to generate a PDF should factor out the directory name;
%.pdf: %.gv
dot -Tpdf -o $# $^
Now, if make tries to create $(FIGS)/ick.pdf, the input will be $(FIGS)/ick.gv - the pattern says to substitute the extension .gv with the extension .pdf, and the rest of the file name stays unmodified, exactly like you'd want. A rule like
%.pdf: $(FIGS)/%.gv # error, don't use
says you need to find the source file in a subdirectory $(FIGS); so if you tried to make $(FIGS)/ick.pdf, that means make would need to find or generate $(FIGS)/$(FIGS)/ick.gv as input according to this rule.
If you absolutely cannot predict what files will be created on step (2) (and so confined to using $(wildcard ...)), you still must execute it after (2) is finished.
It's ugly but I can't think of better alternative than using "recursive make". I mean something like this:
...
.PHONY: images pdf
images: figures
# use figures to generate all .gv files
##figures --create-all-gv-files
# invoke make recursively
#$(MAKE) --no-print-directory pdf
# ensure $(wildcard ...) is invoked only if needed
ifeq ($(MAKECMDGOALS),pdf)
PDF_FILES:=$(patsubst %.gv,%.pdf,$(wildcard $(FIGS)/*.gv))
endif
pdf: $(PDF_FILES)
%.pdf: %.gv
dot -Tpdf -o $# $<

Makefile to auto compile, assemble and link many files in a directory

Sorry for repetition, but I could not find the solution.
Following is the sequence of the commands I want Makefile to accomplish.
gcc-elf-gcc -S -combine loadStoreByte.c string.c lib_uart.c bubble_uart.c -o bubble_uart.s
gcc-elf-as -o startup.o startup.s;
gcc-elf-as -o handler.o handler.s;
gcc-elf-as -o bubble_uart.o bubble_uart.s;
gcc-elf-ld -o bubble_uart -T browtb.x bubble_uart.o startup.o handler.o;
That is, I want to compile all C files into a single S file and then assemeble all s files into corresponding object files and the link all object files into one executable.
I tried the following makefile. The individual targets work fine, but could not run all the target at the same time using "make all".
Please guide how to fix it.
CC = brownie32-elf-gcc
AS = brownie32-elf-as
LK = brownie32-elf-ld
SFILE = $(wildcard *.s)
OFILE = $(patsubst %.s,%,$(SFILE))
CFILE = $(wildcard *.c)
OBJ = $(wildcard *.o)
APP = bubble_uart
all: compile assemble link
link: $(OBJ)
$(LK) -o $(APP) -T browtb.x $^
assemble: $(OFILE)
%: %.s compile
$(AS) -o $#.o $<
compile: $(CFILE)
$(CC) -S -combine $^ -o $(APP).s
clean:
rm -f $(OBJ) $(APP) $(APP).s *.o
Thanks
Your makefile is not written with "best practices" and because of that it was easy for you to make mistakes. I will re-write your makefile here, with best practices, which solves all your problems. Please study it with the aid of the GNU Make manual.
The biggest single problem is that you have "procedures/actions", such as "assemble" as make targets. This makes the makefile into a kind of "procedural" program. GNU Make is not designed to be a procedural language, instead, it is a declarative language. The "targets" should not be actions, but actual files, or "phony" files, which should be collections of actual files.
The use of wildcard in makefiles is a bad idea - it is best to list your files explicitly, as I have shown.
Please consult my answer
makefile enforce library dependency ordering
for a discussion of good practices, including phony and real targets.
MAKEFILE := $(lastword $(MAKEFILE_LIST))
CFILES := \
loadStoreByte.c \
string.c \
lib_uart.c \
bubble_uart.c
SFILE_OUTPUT := bubble_uart.s
SFILES := $(SFILE_OUTPUT) \
startup.s \
handler.s
OFILES := $(SFILES:s=o)
APP := bubble_uart
.PHONY: all
all: $(APP)
$(APP): browtb.x $(OFILES) $(MAKEFILE)
gcc-elf-ld -o $# -T $< $(OFILES)
$(OFILES): %o : %s $(MAKEFILE)
gcc-elf-as -o $# $<
$(SFILE_OUTPUT): $(CFILES) $(MAKEFILE)
gcc-elf-gcc -S -combine $(CFILES) -o $#
It is usually best if the target of a rule is the name of the file the rule produces.
So the compile rule:
compile: $(CFILE)
$(CC) -S -combine $^ -o $(APP).s
should be this:
$(APP).s: $(CFILE)
$(CC) -S -combine $^ -o $#
Likewise the object rule:
%: %.s compile
$(AS) -o $#.o $<
should be this:
%.o: %.s
$(AS) -o $# $<
(There's no reason for it to depend on compile or $(APP).s, since bubble_uart.s is irrelevant to most object files.)
Then the list of object files should include bubble_uart.o:
SFILES = $(sort $(wildcard *.s) $(APP).s)
OFILES = $(patsubst %.s,%.o,$(SFILES))
(The sort is to remove duplicates.) Note that this is the list of object files needed for construction of the executable, not the list of object files that happen to exist at the beginning of the build process.
Finally, the executable:
$(APP): $(OFILES)
$(LK) -o $# -T browtb.x $^

ARM GNU Makefile folder dependency timestamp issue

I would like to develop a little kernel for my new raspberry pi and used this course : http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/
to understand it. Well when I download a example from this site with more than one source file it compiles the first correctly and then tell me the following: make *** no rule to build target 'build/', needed by 'build/gpio.o'.Stop.
Let me explain. There is a folder sources which contains all source files.In the makefile these files are compiled to .o files in the build folder, but the build folder is ALSO set as dependency when compiling a assembler file. So when the first file is compilied and the build folder created, the folders timestamp is outdated and the second compiling file cant use this directory as a dependency. That is the problem to solve, but I have no idea how.
Here is the makefile:
ARMGNU ?= arm-none-eabi
# The intermediate directory for compiled object files.
BUILD = build/
# The directory in which source files are stored.
SOURCE = source/
# The name of the output file to generate.
TARGET = kernel.img
# The name of the assembler listing file to generate.
LIST = kernel.list
# The name of the map file to generate.
MAP = kernel.map
# The name of the linker script to use.
LINKER = kernel.ld
# The names of all object files that must be generated. Deduced from the
# assembly code files in source.
OBJECTS := $(patsubst $(SOURCE)%.s,$(BUILD)%.o,$(wildcard $(SOURCE)*.s))
# Rule to make everything.
all: $(TARGET) $(LIST)
# Rule to remake everything. Does not include clean.
rebuild: all
# Rule to make the listing file.
$(LIST) : $(BUILD)output.elf
$(ARMGNU)-objdump -d $(BUILD)output.elf > $(LIST)
# Rule to make the image file.
$(TARGET) : $(BUILD)output.elf
$(ARMGNU)-objcopy $(BUILD)output.elf -O binary $(TARGET)
# Rule to make the elf file.
$(BUILD)output.elf : $(OBJECTS) $(LINKER)
$(ARMGNU)-ld --no-undefined $(OBJECTS) -Map $(MAP) -o $(BUILD)output.elf -T $(LINKER)
# Rule to make the object files.
$(BUILD)%.o: $(SOURCE)%.s $(BUILD)
$(ARMGNU)-as -I $(SOURCE) $< -o $#
$(BUILD):
mkdir $#
# Rule to clean files.
clean :
-rm -rf $(BUILD)
-rm -f $(TARGET)
-rm -f $(LIST)
-rm -f $(MAP)
PS::
YEEAAYY I've got it.Are working for that for days but now :)
Look again at the page with this example: `OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o : %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
all: $(OBJS)
$(OBJS): | $(OBJDIR)
$(OBJDIR):
mkdir $(OBJDIR)`
I just deleted the $(BUILD) folder dependency from the targets and wrote:
$(OBJECTS): | $(BUILD)
So now it works perfect here the few lines I changed:
$(BUILD)%.o: $(SOURCE)%.s
$(ARMGNU)-as -I $(SOURCE) $< -o $#
$(OBJECTS): | $(BUILD)
What you want to do is make $(BUILD) an order-only prerequisite:
$(BUILD)%.o: $(SOURCE)%.s | $(BUILD)

Getting a list of all dependencies in make

I'm trying to write an etags target in make based on the dependency information generated by gcc. Is there some way of getting at all the dependencies in one go? Or, failing that, how would I write a rule that is only executed when the "tags" target is made and that passes all the source and header files to etags? I only want to index the files actually compiled (including headers). I'm aware that I can sed around in the .d files myself but I'm trying to find a more elegant and less brittle solution.
I have the following (excerpt)
DEPFILES = $(OBJFILES:.o=.d)
%.o : %.c
#echo "Compiling $<"
$(NO_ECHO) $(CC) $(CFLAGS) -MMD -MF $(#:.o=.d) -o $# -c $<
%.o : %.S
#echo "Compiling $<"
$(NO_ECHO) $(CC) $(ASFLAGS) -MMD -MF $(#:.o=.d) -o $# -c $<
$(TARGET) : $(OBJFILES)
#echo "Linking $#"
$(NO_ECHO) $(LD) $(LDFLAGS) -o $# $(OBJFILES) $(LIBS:%=-l%)
.PHONY: clean
# Order-only dependency to make Dep/obj-directories if they are not
# present
$(OBJFILES) : | $(ALLPATHS)
$(ALLPATHS):
$(NO_ECHO) mkdir -p $(ALLPATHS)
# Depend on the makefiles
$(OBJFILES) : $(SRC_PATH)/Makefile $(MAKECFG) $(BUILDCFG)
# Include dependency files
sinclude $(DEPFILES)
Edit : The following seems to work but I'd really like to find a more elegant solution
(the double sort/uniq is just for performance).
tags : $(TARGET)
cat $(DEPFILES) | sort | uniq | sed 's/.*:.*$$//' | tr -d '\\' | tr "\n" " " | xargs -n 1 readlink -f | sort | uniq | xargs etags -a
I came here looking for an answer to the same thing as the original question, but went away as didn't think it was adequately answered and found a solution that doesn't require sed etc.
Below I assume a Makefile similar to the Makefile in the original question which generates dep files using the compiler and includes them.
For the compiling rule where the .d files are generated, I modified the compiler options to ask it to also make the tags target depend on the dependancies of the object file. I added -MQ $# -MQ tags to the options. These options explicitly tell the compiler the names of the target for the dependancies.
%.o : %.c
$(CC) $(CFLAGS) -MMD -MF $(#:.o=.d) -o $# -c $< -MQ $# -MQ tags
Now we don't need to explicitly give the tags target a list of dependencies, it will be generated when we compile and will be updated accordingly as the source files change. In my case I am using ctags and this is what the options are I used it with:
tags:
ctags $^ -o $#
The $^ variable is the list of dependancies. This will be a list of source and header files as each .d file will look something like this:
main.o tags: main.c a.h b.h
Hope that helps.
You need to create a mini tag file for each .d file and then use that to update your etags file. Note this appends stuff to the file, rather than removing and replacing, so you might need to remote the tags file occasionally (ctags has a --update option)
TAGFILES = $(OBJFILES:.o=.t)
# prune the .d files a bit to get a list of files for etags to scan
%.t: %.d
cat $< | sed stuff > $#
cat $# | etags -a $#
.PHONY: tags
tags: $(TAGFILES)

How to process specific files and link them?

I've found something for compiling text file as string variable:
Code:
objcopy --input binary --output elf64-x86-64 --binary-architecture i386 test.txt test.o
and i want to do it for each ./included_text/*.abc and then each of these files link.
I've find pre/post build steps but i can't find anything which will help me. Or you can explain how to do whole makefile if it's easier.
output:
text_files:= $(wildcard *.txt)
text_objects:=$(addsuffix .o,$(basename $(text_files)))
objects=$(text_objects) $(other_objects)
%.o: %.txt
objcopy --input binary $(OBJCOPY_FLAGS) $< $#
output: $(objects)
echo linking $# from $^
#ld ....

Resources