Makefile with subdirectories with sequential numbering - makefile

I have, in the main repository some subdirectories called assignment_1, assignment_2, ..., assignment_n.
I'm tring to write a Makefile that compiles the all TeX files inside those subdirectories.
This is what I have so far, but it doesn't work:
.PHONY: papers clean
PUBLISH_DIR := publish
TEX_DIR := .tex
SRC_DIR := assignment_$(wildcard *)
SRC_FILES := $(wildcard $(SRC_DIR)/*.tex)
CC := xelatex
FLAGS := -shell-escape -output-directory=$(TEX_DIR)
all: $(patsubst $(SRC_DIR)/%.tex, $(PUBLISH_DIR)/%.pdf, $(SRC_FILES))
$(PUBLISH_DIR)/%.pdf: $(SRC_DIR)/%.tex
mkdir -p $(TEX_DIR)
$(CC) $(FLAGS) $<
$(CC) $(FLAGS) $<
mkdir -p $(PUBLISH_DIR)
mv $(TEX_DIR)/*.pdf $(PUBLISH_DIR)/
clean:
rm -rf $(PUBLISH_DIR) $(TEX_DIR)
If I change this line
SRC_DIR := assignment_$(wildcard *)
with
SRC_DIR := assignment_1
it works beautifully but (obviously) only with the TeX file inside assignment_1.
Beside traversing the subdirectories, is there anything else I can improove in this Makefile?

I think you should modify your wildcard:
SRC_DIR := assignment_$(wildcard *)
to
SRC_DIR := $(wildcard assignment_*)

If $(wildcard *) expands to 1 2 3 then assignment_$(wildcard *) will expand to assignment_1 2 3 which is clearly not what you want.
Try this:
SRC_DIR := $(addprefix assignment_,$(wildcard *))
to add the assignment_ prefix to the start of each word.

Related

Move multiple files for different folders using Make

Have two files, namely pyproject.toml and poetry.lock which is located in a folder called dump. I want to move those files to 2 directories for when running tests.
Today I do thise
PROJECT_DIR := $(realpath $(CURDIR))
BUILD_DUMP_DIR := $(PROJECT_DIR)/dump
DESTINATION_DIRS := unit system endtoend
PY_SOURCES = $(patsubst %,$(BUILD_DUMP_DIR)/%, pyproject.toml)
POETRY_SOURCES = $(patsubst %,$(BUILD_DUMP_DIR)/%, poetry.lock)
PY_PROJECT = $(foreach dir, $(DESTINATION_DIRS), $(patsubst %, $(BUILD_DUMP_DIR)/tests/$(dir)/%, pyproject.toml))
POETRY_PROJECT = $(foreach dir, $(DESTINATION_DIRS), $(patsubst %, $(BUILD_DUMP_DIR)/tests/$(dir)/%, poetry.lock))
$(PY_PROJECT): $(PY_SOURCES)
#echo "=> Moving $< to $#"
#cp $< $#
$(POETRY_PROJECT): $(POETRY_SOURCES)
#echo "=> Moving $< to $#"
#cp $< $#
copy-dump: $(PY_PROJECT) $(POETRY_PROJECT)
so running make copy-dump will move those files to the specified directory. Realize there must be nicer MakeFile command to do this. Thanks for all input
Not sure I understood all details but if you use GNU make and you want to copy (not move) your 2 files to 3 different locations each, the following is a bit simpler:
PROJECT_DIR := $(realpath $(CURDIR))
BUILD_DUMP_DIR := $(PROJECT_DIR)/dump
DESTINATION_DIRS := unit system endtoend
PY_SOURCES = $(BUILD_DUMP_DIR)/pyproject.toml
POETRY_SOURCES = $(BUILD_DUMP_DIR)/poetry.lock
PY_PROJECT = $(patsubst %,$(BUILD_DUMP_DIR)/tests/%/pyproject.toml,$(DESTINATION_DIRS))
POETRY_PROJECT = $(patsubst %,$(BUILD_DUMP_DIR)/tests/%/poetry.lock,$(DESTINATION_DIRS))
.PHONY: copy-dump
copy-dump: $(PY_PROJECT) $(POETRY_PROJECT)
.SECONDEXPANSION:
$(PY_PROJECT) $(POETRY_PROJECT): $(BUILD_DUMP_DIR)/$$(notdir $$#)
#echo "=> Moving $< to $#"
#cp $< $#
See the GNU make documentation for the details about secondary expansion.

GNU make path substitution (directory flattening)

I have a makefile that gives me the source files in a hierarchy.
SRCS := $(wildcard $(SRC_DIR)/*.c $(SRC_DIR)/*/*.c)
gives me
./src/main.c ./src/add/add.c ./src/sub/sub.c
I want to flatten the object files into a single "obj" directory.
Of course
OBJS := $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.obj)
gives me
./obj/main.obj ./obj/add/add.obj ./obj/sub/sub.obj
instead of desired
./obj/main.obj ./obj/add.obj ./obj/sub.obj
Question: How do I get rid of additional source directory levels?
Never had to use complex substitution so far. My intuitive try with additional "/%" in pattern
# won't work as expected:
OBJS := $(SRCS:$(SRC_DIR)/%/%.c=$(OBJ_DIR)/%.obj)
produces no meaningful result (${OBJS} becomes same as ${SRCS}).
All examples I found so far only have single occurance of "%" in match pattern.
MAK_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
SRC_DIR = $(MAK_DIR)./src
OBJ_DIR = $(MAK_DIR)./obj
# gives: ./src/main.c ./src/add/add.c ./src/sub/sub.c
SRCS := $(wildcard $(SRC_DIR)/*.c $(SRC_DIR)/*/*.c)
# gives: ./obj/main.obj ./obj/add/add.obj ./obj/sub/sub.obj
OBJS := $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.obj)
.PHONY : all
all :
#echo $(SRCS)
#echo $(OBJS)
Just use the notdir function, and also patsubst, more powerful (and that I find easier to understand than the shorthand):
OBJS := $(patsubst %.c,$(OBJ_DIR)/%.obj,$(notdir $(SRCS)))
But it is not the whole story because later on you will probably want to do something like:
$(OBJ_DIR)/%.obj: $(SRC_DIR)/%.c
which will not work any more. Not mentioning the fact that you could have several source files with the same name in different directories. Assuming you do not have such names conflicts you can generate all your dependencies using foreach-eval-call:
MAK_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
SRC_DIR := $(MAK_DIR)./src
OBJ_DIR := $(MAK_DIR)./obj
SRCS := $(shell find $(MAK_DIR) -type f -name '*.c')
OBJS := $(patsubst %.c,$(OBJ_DIR)/%.obj,$(notdir $(SRCS)))
.PHONY: objs
objs: $(OBJS)
# $(1): source file
define DEP_rule
$(1)-obj := $$(patsubst %.c,$$(OBJ_DIR)/%.obj,$$(notdir $(1)))
$(1)-dep := $$(patsubst %.c,$$(OBJ_DIR)/%.d,$$(notdir $(1)))
$$($(1)-obj): $(1) $$($(1)-dep)
endef
$(foreach src,$(SRCS),$(eval $(call DEP_rule,$(src))))
Just remember that the DEP_rule macro gets expanded twice, thus the $$.

Makefile: pick the right file

I have a source code with thousands of media files and the following file structure:
files/module/file.vid
files/module/lang/file.vid
if 'files/module/lang/file.vid' exists, I want to copy it to target as is.
if not, I want to copy 'files/module/file.vid' into 'files/module/lang/file.vid' in target.
How can I do that with makefile?
PS: to be more precise, can the solution fit in the current piece below?
$(foreach lang,$(filter-out en-US,$(gb_HELP_LANGS)),$(eval $(call gb_AllLangPackage_add_files_for_lang,helpcontent2_html_media_lang,$(lang),$(LIBO_SHARE_HELP_FOLDER)$(if $(HELP_ONLINE),/$(PRODUCTVERSION))/media, \
files/scalc/$(lang)/imtrigon.vid \
files/scalc/$(lang)/trigon.vid \
files/scalc/$(lang)/pivot.vid \
files/scalc/$(lang)/functions_ifs.vid \
)))
Thanks
You can do this:
VIDDIR := files/module
LANGDIR := $(VIDDIR)/lang
TARGETDIR := target
VIDFILES := $(notdir $(wildcard $(VIDDIR)/*.vid))
TARGETVIDS := $(addprefix $(TARGETDIR)/,$(VIDFILES))
LANGVIDS := $(addprefix $(LANGDIR)/,$(VIDFILES))
all: $(TARGETVIDS) $(LANGVIDS)
$(TARGETDIR)/%.vid : $(LANGDIR)/%.vid
cp $< $#
$(LANGDIR)/%.vid: $(VIDDIR)/%.vid
cp $< $#

Need help in my makefile to compile a source code

I have 2 folders with their subfolders 04-Software Components / 03-Specific_sources and 08-Ext_Proj / SWC_ADC, SWC_PWM / 03-SRC
There are some .c and .h files in 03-Specific_sources and there is one .c file and their .h
files in both SWC_ADC / 03-SRC (which is ADC.c) and
SWC_PWM / 03-SRC (which is PWM.c)
And I want to compile them and link them all to get the output file.
so what I did is this:
EXEDIR_RELEASE := ../01-EXE\02-Release
OBJDIR_RELEASE := ../05-Obj\02-Release
SRCDIR := ../../../03-Specific_sources (This is the path from my make folder)
EXT_DIR := ../../08-Ext_Proj (This is the path from my make folder)
FIND_SRCS := $(wildcard $(EXT_DIR)/SWC_*/03-SRC/*.c)
INCLUDES := -I $(SRCDIR) $(foreach ext, $(wildcard $(EXT_DIR)/SWC*), -I $(ext)/03-SRC)
CSRCS := $(wildcard $(SRCDIR)/*.c) $(FIND_SRCS)
CSRCS := $(notdir $(CSRCS))
CROBJS := $(patsubst %.c, %.r34, $(CSRCS))
CROBJS := $(addprefix $(OBJDIR_RELEASE)/, $(CROBJS))
.PHONY: all
all: $(EXEDIR_RELEASE)/$(TARGET_RELEASE)
# Compiling
$(OBJDIR_RELEASE)/%.r34: $(FIND_SRCS)
#echo '$^ $#'
$(CC) $(CFLAGS) $(INCLUDES) -o $# $<
# Linking
$(EXEDIR_RELEASE)/Target.mot: $(CROBJS)
$(LD) $(MFLAGS) # These are the linker and its flags
The problem is that the compilation is not working. So when I do the echo I get this:
ADC_prg.c PWM_prg.c DDF_prg.r34
ADC_prg.c PWM_prg.c DFAN_prg.r34
ADC_prg.c PWM_prg.c DFN_prg.r34
ADC_prg.c PWM_prg.c DIO_prg.r34
ADC_prg.c PWM_prg.c DMIO_prg.r34
So I think that the mathing pattern %.r34 is not working and when I use
($(OBJDIR_RELEASE)/%.r34: $(FIND_SRCS)/%.c) it also not working because I can't use %
with a variable that has wildcard function performed on it.
I also used the foreach function but with no use.
So please I need your help guys, I have a delivery today... please respond asap.
Thanks in advance
SAM
This makefile has a lot of problems. Notably:
$(OBJDIR_RELEASE)/%.r34: $(FIND_SRCS)
#echo '$^ $#'
$(CC) $(CFLAGS) $(INCLUDES) -o $# $<
This pattern rule has no wildcard ("%") in the prerequisite list. Any r34 target depends on all sources in $(FIND_SRCS). If that isn't bad enough, look at where these variables come from:
SRCDIR := ../../../03-Specific_sources (This is the path from my make folder)
EXT_DIR := ../../08-Ext_Proj (This is the path from my make folder)
FIND_SRCS := $(wildcard $(EXT_DIR)/SWC_*/03-SRC/*.c)
...
CSRCS := $(wildcard $(SRCDIR)/*.c) $(FIND_SRCS)
CSRCS := $(notdir $(CSRCS))
CROBJS := $(patsubst %.c, %.r34, $(CSRCS))
CROBJS := $(addprefix $(OBJDIR_RELEASE)/, $(CROBJS))
In other words, you seem to expect that for every source file in one directory there will be a file of the same name in the other directory. According to your echo statements, there are no such matches.
There are other problems, but this is a good place to start. Try this:
CSRCS := $(wildcard $(SRCDIR)/*.c) $(EXT_DIR)/SWC_ADC/03-SRC/ADC.c $(EXT_DIR)/SWC_PWM/03-SRC/PWM.c
CSRCS := $(notdir $(CSRCS))
CROBJS := $(patsubst %.c, $(OBJDIR_RELEASE)/%.r34, $(CSRCS))
vpath %.c $(SRCDIR) $(EXT_DIR)/SWC_ADC/03-SRC $(EXT_DIR)/SWC_PWM/03-SRC
$(OBJDIR_RELEASE)/%.r34: %.c
$(CC) $(CFLAGS) $(INCLUDES) -o $# $<
Go down the list of object files you want to build, and try building each one:
make DDF_prg.r34
make DFAN_prg.r34
...
If that works, try linking them by hand, and if that works, take a look at the linking rule -- which looks completely wrong but which I can't really diagnose because I don't know what linker you're using.

Outputting obj files to obj directory in Makefile

Hi I wrote this Makefile by modifying this example: https://sites.google.com/site/michaelsafyan/software-engineering/how-to-write-a-makefile
program_NAME := bin/myprogram
SRC_DIR := src
#
#srces
#
program_C_SRCS := $(wildcard $(SRC_DIR)/*.c)
program_CXX_SRCS := $(wildcard $(SRC_DIR)/*.cpp)
#
#obj files
#
program_C_OBJS := ${program_C_SRCS:.c=.o}
program_CXX_OBJS := ${program_CXX_SRCS:.cpp=.o}
program_OBJS := $(program_C_OBJS) $(program_CXX_OBJS)
#
# include and library dirs; also libraries
#
program_INCLUDE_DIRS := inc
program_LIBRARY_DIRS :=
program_LIBRARIES :=
# flags
CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir))
LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir))
LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library))
#
# targets
#
.PHONY: all clean distclean
all: $(program_NAME)
$(program_NAME): $(program_OBJS)
$(LINK.cc) $(program_OBJS) -o $(program_NAME)
clean:
#- $(RM) $(program_NAME)
#- $(RM) $(program_OBJS)
distclean: clean
It works in the following way. The classes below are compiled into an executable "myprogram" which is output in the bin directory. The only issue is the object files are created inside the src folder, instead of the obj folder. How can I modify this makefile such that obj files are created in the obj folder? Thank you.
/project
Makefile
/src
Class1.cpp
Class2.cpp
main.cpp
/obj
/bin
myProgram
/inc
Class1.h
Class2.h
To start with, you could use e.g. the subst function to replace the source-file directory with the object-file directory:
program_OBJS = $(subst $(SRC_DIR),$(OBJ_DIR),$(program_C_OBJS))
program_OBJS += $(subst $(SRC_DIR),$(OBJ_DIR),$(program_CXX_OBJS))
Of course you now need to add a target for object-file creation, as these will not be put in the correct place otherwise:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c -o $# $<
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -c -o $# $<
Try with something like:
OUT_DIR=obj
program_bare_OBJS := $(program_C_OBJS) $(program_CXX_OBJS)
program_OBJS=$(addprefix $(OUT_DIR)/,$(program_bare_OBJS))

Resources