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 $< $#
Related
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.
I have been working with a project that only compiles C sources but I've found I need some assembler too, I'm reticent to inline the asm code in a C file as GCC may not interpret it correctly.
My predecesor created the makefile for the project (apologies, it's fairly long):
# Compiler and options
CC := sparc-rtems-gcc
# The application software binary
TARGET := icu_asw
# Source and build directories
SRCDIR := src
BUILDDIR := obj
TARGETDIR := bin
HDSWROOT := ../../hdsw
BSWTOOLS := ../../bsw/sw/tools
SRCEXT := c
DEPEXT := d
OBJEXT := o
MRAMEXT := img.elf
# Flags, libraries and includes
CFLAGS := -std=gnu99 -Wall -Wextra -g
LIBDRV := $(HDSWROOT)/lib/libdrv.a
INCFLAGS := -I$(HDSWROOT)/include -I$(HDSWROOT)/osal/rtems
# Debug flags
DEBUGFLAGS = -DLOGERROR=1 -DLOGWARN=1 -DLOGDEBUG=1 -DLOGINFO=1 -DMAKECHECKS=1
NODEBUGFLAGS = -DLOGERROR=1 -DLOGWARN=0 -DLOGDEBUG=0 -DLOGINFO=0 -DMAKECHECKS=1
#-----------------------------------------------------------------------
# Build instructions
#-----------------------------------------------------------------------
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.$(OBJEXT)))
# Default make
all: $(TARGET)
# Remake
remake: cleaner all
# Clean only objects
clean:
#$(RM) -rf $(BUILDDIR)
# Full clean (objects and binaries)
cleaner: clean
#$(RM) -rf $(TARGETDIR)
# Pull in dependency info for *existing* .o files
-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))
# Link (uses an order-only prerequisite for the directories so that they
# don't affect the use of the $^)
$(TARGET): $(OBJECTS) | directories
$(CC) -o $(TARGETDIR)/$(TARGET) $^ $(LIBDRV)
# Make the build and target directories
directories:
#mkdir -p $(TARGETDIR)
#mkdir -p $(BUILDDIR)
# Compile
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT)
#mkdir -p $(dir $#)
$(CC) $(CFLAGS) $(INCFLAGS) $(NODEBUGFLAGS) -c -o $# $<
#$(CC) $(CFLAGS) $(INCDEP) -MM $(SRCDIR)/$*.$(SRCEXT) > $(BUILDDIR)/$*.$(DEPEXT)
#cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
#sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
#sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
#rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
# Non-File Targets
.PHONY: all remake clean cleaner
I want to also bring in and compile two .S files, so, I edited the following line
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT) -or -name *.$(ASMEXT))
To bring in the .S files, then I edited the OBJECTS to also include the ASM sources ("*.S")
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.$(OBJEXT)),$(SOURCES:.$(ASMEXT)=.$(OBJEXT)))
But when recompiling with 'make all' I'm getting:
$ make all
make: *** No rule to make target `obj/asi_access.S', needed by `icu_asw'. Stop.
I don't suppose someone could spot where I am going wrong? I think I have not correctly added to the OBJECTS line!
Thanks
The expression $(var:.ext1=.ext2) does not filter by .ext1, i.e.
$(SOURCES:.$(SRCEXT)=.$(OBJEXT)) $(SOURCES:.$(ASMEXT)=.$(OBJEXT))
gives for a test source list the following result
a.o b.o c.S a.c b.c c.o
I.e. you duplicated your files and you have source files in the OBJECTS definition.
The following would be a correct approach:
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%, \
$(patsubst %.$(SRCEXT),%.$(OBJEXT), \
$(patsubst %.$(ASMEXT),%.$(OBJEXT),$(SOURCES)) \
) \
)
UPDATE: you should consider to use 2 separate object lists, so that you can apply different rules for them, e.g.
SOURCES_C := $(filter %.$(SRCEXT),$(SOURCES))
OBJECTS_C := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES_C:%.$(SRCEXT)=%.$(OBJEXT)))
SOURCES_ASM := $(filter %.$(ASMEXT),$(SOURCES))
OBJECTS_ASM := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES_ASM:%.$(ASMEXT)=%.$(OBJEXT)))
$(OBJECTS_C): $(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT)
.... C compiler recipe ....
$(OBJECTS_ASM): $(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(ASMEXT)
.... assembler recipe ....
$(TARGET): $(OBJECTS_C) $(OBJECTS_ASM) | directories
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.
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.
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))