I have a Makefile that builds a shapefile as an intermediate steps.
.INTERMEDIATE : senate_boundaries.shp
senate_boundaries.shp : Senate\ shape\ files.zip
unzip -j "$<"
A full shapefile comes with more than just a .shp, but also a .prj file, a .dbf file, and a bunch of others. These files are created when "Senate shape files.zip" is unzipped.
These other files are never an explicit target or dependency.
.INTERMEDIATE : senate_boundaries.prj senate_boundaries.dbf
does not seem to do anything.
How can I tell Make to clean up these other files?
You can add something like this to your recipe:
rm -f $(wildcard Senate\shape\*.prj)
But that will only work for that one file and you would have to manually add each extension to get rid of.
so something like this might do the trick:
rm -f $(shell ls Senate\shape\ | grep -v .shp&)
Another option is to unzip into a temp directory and then copy the file you want out and remove the the temp directory.
Related
Suppose I need to download a zipped archive containing thousands of compressed CSV files, and unzip it, and I want to use make for that process. The first step is easy:
myarchive.zip:
curl -o myarchive.zip 'http://path/to/archive.zip'
But before downloading the archive, I don't know the name of every file in it. This doesn't work.
extracted/*.csv: myarchive.zip
unzip myarchive.zip -d extracted
How do I let make know that all of these CSV files are targets?
It's not clear exactly what you want, but this is probably close:
ARCHIVE_DIR := extracted
.PHONY: archive
archive: myarchive.zip
unzip $< -d $(ARCHIVE_DIR)
myarchive.zip:
curl -o $# 'http://path/to/archive.zip'
I have a build system setup for a library using the GNU autotools. The library has subdirectories for source and header files. It also contains a script in the top directory which auto-generates a source and header file (not the same as the config file) in the appropriate subdirectories. It is necessary that these files are generated before make is performed in the subdirectories.
What is the simplest way to have the script run before subdirectories are traversed (i.e. when user calls make, the script is ran before traversing SUBDIRS)? I have tried adding rules like all-local with no success.
EDIT:
Top-level directory:
configure.ac Makefile.am src include myscript.sh
Makefile.am:
EXTRA_DIST = myscript.sh
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4
SUBDIRS = src include
.PHONY: gen-script
gen-script:
./myscript.sh
src/Makefile.am:
AM_CPPFLAGS = -I$(top_srcdir)/include
lib_LTLIBRARIES = libmylib.la
libmylib_la_SOURCES = \
file1.cxx \
file2.cxx \
autogen-file.cxx
clean-local:
rm -f autogen-file.cxx
include/Makefile.am:
nobase_include_HEADERS = \
file1.h \
file2.h \
autogen-file.h
clean-local:
rm -f autogen-file.h
I think that the best solution would be to get rid of the recursive make and only have the top-level Makefile.am. Then you'd simply add a rule
include/autogen-file.h src/autogen-file.cxx: myscript.sh
${SHELL} $<
and list include/autogen-file.h in BUILT_SOURCES.
If you want to keep your recursive structure (even if this is considered harmful), you could place the rule to generate the files into the Makefile.ams in the sub-directories.
In src/Makefile.am:
autogen-file.cxx: ../myscript.sh
cd ${top_srcdir} && ${SHELL} myscript.sh
And in include/Makefile.am:
autogen-file.h: ../myscript.sh
cd ${top_srcdir} && ${SHELL} myscript.sh
By the way, how often do you need to re-build those? If the generated files only depend on the project configuration, you could simply run myscript.sh at the end of your configure.ac and delete the generated files only on make distclean.
What you can do is force the current directory to run before the rest of the subdirectories with
SUBDIRS = . src include
More seriously, though, you should not use recursive automake. Particularly if your structure is relatively simple as it seems to be. If you have interests in looking up how to do that you can see my documentation on Autotools Mythbuser.
I have a number of binary files (images, etc.). I need to copy some of them to an output directory as part of my build process.
The list of files that need to be copied is based on some rather complex logic, and it are generated dynamically by a Python script.
Suppose I have the following in deps.txt:
a.png
b.gif
c.mp4
How could I use a makefile to copy any necessary files to the output directory?
For example, if the output directoryalready included c.mp4 and an out-of-date version of b.gif, running the makefile would copy a.png and b.gif to the output directory (but not c.mp4).
The simplest way, if you're using GNU make, is to use an auto-generated include file, like this:
deps.txt.mk: deps.txt
cat $< | while read f; do echo "\$$(OUTPUT_DIR)/$$f: $$f ; cp $$< $$#"; done > $#
-include deps.txt.mk
If you're not using GNU make, you'll have to use recursion instead: have a rule that creates the makefile (like above), then run $(MAKE) -f deps.txt.mk to actually do the installation. Let me know if you need that example.
I have an existing project where I am adding gettext support. Unfortunately, due to the project's structure and limitations, I cannot go through the recommended route of changing the project over to automake. Also unfortunately, my make-fu is pretty weak and I'm having troubles implementing rules to build my output archive:
Take all .po files in the msg subdir and run msgfmt on them to produce .mo files (in my target dir)
Put the .po files in the directory structure expected by gettext: (dir)/(locale)/LC_MESSAGES/(domainname).mo
Here's what I have so far
MSGSRC=msg/*.po
MSGOBJ=$(addprefix $(TARGET_BUILD_PATH)/$(target)/,$(MSG_SRC:.po=.mo))
$(TARGET_BUILD_PATH)/$(target)/msg/%.mo: msg/%.po
msgfmt -c $< -o $#
# Put in correct place
mkdir -p $(TARGET_BUILD_PATH)/$(target)/msg/$(*F)/LC_MESSAGES
cp $# $(TARGET_BUILD_PATH)/$(target)/msg/$(*F)/LC_MESSAGES/myapp.mo
archive: $(MSGOBJ) (other objs....)
(make the archive tarball...)
The problem with the existing code is that for some reason $(*F) comes out just * instead of the locale name (the .po files are named en_US.po, etc). It also seems incorrect because the target should be the real target, not the hacky msgfmt and copy I have. The directory structure is important because the makefile is run a few times for different cross-compiles ($(target)) and the output is archived into a tarball for installation on the devices.
I assume you can use GNU make.
First of all, let make expand the wildcards. This is important for later postprocessing:
MSGSRC=$(wildcard msg/*.po)
Now you should get lists of file names in MSGSRC and MSGOBJ. Additionally, the make manual marks $(F) as obsolete, and $ (the stem of the name) should contain just the locale. So,
mkdir -p $(TARGET_BUILD_PATH)/$(target)/msg/$*/LC_MESSAGES
should do the trick just fine, the same for the cp rule.
I do it slightly different. Here are my po files:
$ find msg -type f
msg/bg_BG.po
msg/de_DE.po
Here's the Makefile:
MSGLANGS=$(notdir $(wildcard msg/*po))
MSGOBJS=$(addprefix locale/,$(MSGLANGS:.po=.UTF-8/LC_MESSAGES/appname.mo))
gettext: $(MSGOBJS)
locale/%.UTF-8/LC_MESSAGES/appname.mo: msg/%.po
mkdir -p $(dir $#)
msgfmt -c -o $# msg/$*.po
And these are the resulting mo files:
$ find locale -type f
locale/bg_BG.UTF-8/LC_MESSAGES/appname.mo
locale/de_DE.UTF-8/LC_MESSAGES/appname.mo
I would like to delete a another directory when I run make clean, but I can't figure out how to code it up in the rules.
I have tried
clean-local:
-rm -f del.dir
but that didn't work.
I also tried
CLEANFILES = del.dir
but that also didn't work.
Any suggestions would be appreciated,
clean-local should work, but the command to erase a directory is rm -rf dir, not rm -f dir.