I'm trying to add an extra dependency to a rule in a parallel makefile. I might have found a way, but I'm in doubt. (I haven't written the original makefile and I'm not an expert in make.)
The original makefile looks like this:
VER = busybox-1.16.2
URL = http://busybox.net/downloads/$(VER).tar.bz2
export KBUILD_OUTPUT = $(ROOTDIR)/user/busybox/build-$(VER)
all: build-$(VER)/.config depmod.pl
$(MAKE) -C build-$(VER)
build-$(VER)/.config: $(ROOTDIR)/config/.config
mkdir -p build-$(VER)
sed -n \
-e '/_CROSS_COMPILER_PREFIX=/s:=.*:="$(CROSS_COMPILE)":' \
-e '/CONFIG_USER_BUSYBOX_/s:CONFIG_USER_BUSYBOX_:CONFIG_:p' \
$< > $#.uclinux-dist.new
set -e ; \
if [ ! -e $# ] || ! cmp -s $#.uclinux-dist.new $#.uclinux-dist.old ; then \
cp $#.uclinux-dist.new $#.uclinux-dist.old ; \
cp $#.uclinux-dist.old $# ; \
yes "" | $(MAKE) -C $(VER) oldconfig ; \
fi
depmod.pl: $(VER)/examples/depmod.pl
ln -sf $< $#
I want to add a 'download' rule to the make.
$(VER)/: $(VER).tar.bz2
tar -jxvf $(VER).tar.bz2
touch $#
$(VER).tar.bz2:
wget $(URL)
touch $#
This rule must be executed before anything else. The parallel build prevent constructs like
all: |$(VER)/ build-$(VER)/.config depmod.pl
(This works in single threaded builds.)
My solution so far is this:
VER = busybox-1.18.5
URL = http://busybox.net/downloads/$(VER).tar.bz2
export KBUILD_OUTPUT = $(ROOTDIR)/user/busybox/build-$(VER)
all: build-$(VER)/.config depmod.pl
$(MAKE) -C build-$(VER)
$(VER)/: $(VER).tar.bz2
tar -jxvf $(VER).tar.bz2
touch $#
$(VER).tar.bz2:
wget $(URL)
touch $#
build-$(VER)/.config: $(ROOTDIR)/config/.config | $(VER)/
mkdir -p build-$(VER)
sed -n \
-e '/_CROSS_COMPILER_PREFIX=/s:=.*:="$(CROSS_COMPILE)":' \
-e '/CONFIG_USER_BUSYBOX_/s:CONFIG_USER_BUSYBOX_:CONFIG_:p' \
$< > $#.uclinux-dist.new
set -e ; \
if [ ! -e $# ] || ! cmp -s $#.uclinux-dist.new $#.uclinux-dist.old ; then \
cp $#.uclinux-dist.new $#.uclinux-dist.old ; \
cp $#.uclinux-dist.old $# ; \
yes "" | $(MAKE) -C $(VER) oldconfig ; \
fi
depmod.pl: $(VER)/examples/depmod.pl
ln -sf $< $#
$(VER)/examples/depmod.pl: | $(VER)/
Problem is, I don't really know what kind of magic the depmod.pl rule is. Is it executed correctly, now that I've added an explicit empty rule?
I'd hate to answer my own question, but I think I've found the answer.
The dependency of the depmod.pl rule is not real/relevant in the original script.
The code:
depmod.pl: $(VER)/examples/depmod.pl
ln -sf $< $#
Ought to be written:
depmod.pl:
ln -sf $(VER)/examples/depmod.pl $#
So my extra empty rule makes no difference. In the new script, the dependency almost makes sence though.
Related
x86_64_asm_source_files := $(shell find src/impl/x86_64 -name *.asm)
x86_64_asm_object_files := $(patsubst src/impl/x86_64/%.asm, build/x86_64/%.o, $(x86_64_asm_source_files))
$(x86_64_asm_object_files): build/x86_64/%.o : src/impl/x86_64/%.asm
mkdir -p $(dir $#) && \
nasm -f elf64 $(patsubst build/x86_64/%.o, src/impl/x86_64/%.asm, $#) -o $#
.PHONY: build-x86_64
build-x86_64: $(x86_64_asm_object_files)
mkdir -p dist/x86_64 && \
x86_64-elf-ld -n -o dist/x86_64/kernel.bin -T targets/x86_64/linker.ld $(x86_64_asm_object_files) && \
cp dist/x86_64/kernel.bin targets/x86_64/iso/boot/kernel.bin && \
grub-mkrescue /usr/lib/grub/i386-pc -o dist/x86_64/kernel.iso targets/x86_64/iso
I ran a particular Makefile on my Lubuntu machine, and it created a couple directories of files in my /usr/local/lib directory.
Tonight I'm trying to create a similar setup in a cygwin window on my Windows 10 machine. Same Makefile, but the /usr/local/lib directory ends up empty. So when I run a different Makefile later on that wants to call these /usr/local/lib libraries, it fails.
What could I be doing wrong? Is there an environment variable that needs to be set such that the /usr/loal/lib directory can be written to during the make?
Thanks.
Update: I just figured out that I can install Ubuntu as an application in Windows https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/ , and my makefile install is working great now. No problems at all, so it appears to be a cygwin problem only. That being said, here is my make file:
#! /usr/bin/make -f
# -*- make -*-
#
# Main gcc Makefile.
# This makefile is maintained by Greg King <greg.king4#verizon.net>.
# Goals that are supported by the cc65 package
.PHONY: all bins libs docs samples tests clean zap
.PHONY: uninstall install install-bins install-libs install-docs install-samps
# If SYS is defined on this makefile's command-line, then we want it to go
# to "samples" and "tests", but not to the other rules. So, we disable a
# feature of GNU make that would have given ${SYS} to every sub-make.
#MAKEOVERRIDES=
# (That trick has been disabled.)
# To compile with custom make-options, set them here; for example:
#MAKEOPTS = -j 2 CFLAGS=-O4 CC=clang
MAKEOPTS =
# The install prefix and directories
prefix = /usr/local
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin
datadir = $(prefix)/share
docdir = $(datadir)/doc
libdir = $(exec_prefix)/lib
CC65_DOC = $(docdir)/cc65
CC65_HOME = $(libdir)/cc65
CA65_INC = $(CC65_HOME)/asminc
CC65_INC = $(CC65_HOME)/include
LD65_CFG = $(CC65_HOME)/cfg
LD65_LIB = $(CC65_HOME)/lib
LD65_OBJ = $(CC65_HOME)/obj
# Programs
MKDIR = mkdir -m 755
# BSD-like install-script/-program
INSTALL = make/install-sh
INSTALL_DATA = $(INSTALL) -c -m 644
INSTALL_PROG = $(INSTALL) -c -m 755
INSTALL_STRIP = $(INSTALL_PROG) -s
# This file-name extension is needed on DOS/Windows systems.
ifdef COMSPEC
EXT = .exe
endif
# Rules
# The sample and library-test programs must be compiled for only one platform
# at a time. So, those rules are done automatically only when a user names
# a system on the command-line. (A user can do those rules with their
# defaults by putting "all samples tests" on the command-line.)
#
all: bins libs docs $(SYS:%=samples tests)
bins:
#$(MAKE) -C src -f make/gcc.mak $(MAKEOPTS) \
CA65_INC=\\\"${CA65_INC}/\\\" CC65_INC=\\\"${CC65_INC}/\\\" \
LD65_CFG=\\\"${LD65_CFG}/\\\" LD65_LIB=\\\"${LD65_LIB}/\\\" \
LD65_OBJ=\\\"${LD65_OBJ}/\\\"
libs:
#$(MAKE) -C libsrc
# This rule won't try to generate HTML files
# if a host system doesn't have LinuxDoc Tools.
docs:
#if linuxdoc -B check doc/index >/dev/null 2>&1; \
then $(MAKE) -C doc $(MAKEOPTS) html; \
else echo '"LinuxDoc Tools" is not installed; skipping HTML documentation.'; \
fi
# Some platforms cannot compile all of the sample and library-test programs.
# So, these rules ignore errors.
samples:
-#$(MAKE) -k -C samples prefix=$(prefix) $(SYS:%=SYS=%)
tests:
-#$(MAKE) -k -C testcode/lib prefix=$(prefix) $(SYS:%=SYS=%)
clean zap:
#$(MAKE) -C src -f make/gcc.mak $#
#$(MAKE) -C libsrc $#
#$(MAKE) -C doc $#
#$(MAKE) -C samples $#
# #$(MAKE) -C testcode/lib $# $(SYS:%=SYS=%)
uninstall: install-test
cd $(bindir) && $(RM) ar65${EXT} ca65${EXT} cc65${EXT} cl65${EXT} \
co65${EXT} da65${EXT} ld65${EXT} od65${EXT} grc65${EXT} ca65html
$(RM) -R $(CC65_HOME) $(CC65_DOC)
install: install-test install-dirs install-bins install-libs install-docs
#echo
#echo 'If you installed the files into non-default directories, then'
#echo 'you might need to export some shell environment variables:'
#echo
#echo 'CC65_HOME=$(CC65_HOME)'
#echo ' or'
#echo 'CA65_INC=$(CA65_INC)'
#echo 'CC65_INC=$(CC65_INC)'
#echo 'LD65_CFG=$(LD65_CFG)'
#echo 'LD65_LIB=$(LD65_LIB)'
#echo 'LD65_OBJ=$(LD65_OBJ)'
#echo
#if [ -x $(bindir)/grc${EXT} ]; then \
echo 'grc was renamed to grc65; but, a grc command is in your binaries directory.'; \
echo "If that command is an old copy of CC65's program,"; \
echo 'then you should use a "${MAKE} erase-grc" command to remove it.'; \
fi
.PHONY: install-test
install-test:
#if [ `id -u` != 0 ]; then \
echo; \
echo 'If you are denied permission to install or uninstall this package,'; \
echo 'then you will need to do "make/gcc.mak install" or "make/gcc.mak uninstall"'; \
echo 'as either the root user or an administrator.'; \
echo; \
fi 2>/dev/null
.PHONY: install-dirs
install-dirs: $(bindir) $(datadir) $(docdir) $(libdir) \
$(CC65_DOC) $(CC65_HOME) \
$(CA65_INC) $(CC65_INC) \
$(CC65_INC)/em $(CC65_INC)/geos $(CC65_INC)/joystick \
$(CC65_INC)/mouse $(CC65_INC)/sys $(CC65_INC)/tgi \
$(LD65_CFG) $(LD65_LIB) $(LD65_OBJ) \
$(CC65_HOME)/emd $(CC65_HOME)/joy $(CC65_HOME)/mou \
$(CC65_HOME)/ser $(CC65_HOME)/tgi
$(bindir) $(datadir) $(docdir) $(libdir) \
$(CC65_DOC) $(CC65_HOME) \
$(CA65_INC) $(CC65_INC) \
$(LD65_CFG) $(LD65_LIB) $(LD65_OBJ):
$(MKDIR) -p $# || $(MKDIR) $#
$(CC65_HOME)/% $(CC65_INC)/% $(CC65_DOC)/%:
$(MKDIR) $#
install-bins:
for f in ar65 ca65 cc65 cl65 co65 da65 ld65 od65 grc65 sp65; \
do $(INSTALL_STRIP) src/$$f/$$f${EXT} $(bindir) || exit $$?; \
done
$(INSTALL_PROG) src/ca65html/ca65html $(bindir)
install-libs:
for f in asminc/*.inc; \
do $(INSTALL_DATA) $$f $(CA65_INC) || exit $$?; \
done
for f in include/*.h; \
do $(INSTALL_DATA) $$f $(CC65_INC) || exit $$?; \
done
for d in em geos joystick mouse sys tgi; \
do for f in include/$$d/*.h; \
do $(INSTALL_DATA) $$f $(CC65_INC)/$$d || exit $$?; \
done || exit $$?; \
done
for f in libsrc/*.lib; \
do $(INSTALL_DATA) $$f $(LD65_LIB) || exit $$?; \
done
for f in libsrc/*-*.o; \
do $(INSTALL_DATA) $$f $(LD65_OBJ) || exit $$?; \
done
for f in src/ld65/cfg/[!g]*-*.cfg; \
do $(INSTALL_DATA) $$f $(LD65_CFG) || exit $$?; \
done
for d in emd joy mou ser tgi; \
do for f in libsrc/*.$$d; \
do $(INSTALL_DATA) $$f $(CC65_HOME)/$$d || exit $$?; \
done || exit $$?; \
done
install-docs:
for f in src/ca65/macpack/*.mac; \
do $(INSTALL_DATA) $$f $(CC65_DOC) || exit $$?; \
done
for f in readme.1st compile.txt CREDITS BUGS internal.txt newvers.txt; \
do $(INSTALL_DATA) doc/$$f $(CC65_DOC) || exit $$?; \
done
if [ -f doc/index.htm* ]; \
then for f in doc/*.htm*; \
do $(INSTALL_DATA) $$f $(CC65_DOC) || exit $$?; \
done; \
fi
install-samps: ${addprefix $(CC65_DOC)/, $(shell find samples -type d)}
#$(MAKE) -C samples zap
for d in `find samples -type d`; \
do for f in $$d/*; \
do if [ -f $$f ]; \
then $(INSTALL_DATA) $$f $(CC65_DOC)/$$d || exit $$?; \
fi; \
done || exit $$?; \
done
erase-grc:
$(RM) $(bindir)/grc${EXT}
I'd like to simplify the following GNU make rules:
lib/dir1/org/eclipse/jetty/jetty-http/9.3.0.M2/jetty-http-9.3.0.M2.jar:
mkdir -p $(dir $#) && curl -o $# "http://central.maven.org/maven2/org/eclipse/jetty/jetty-http/9.3.0.M2/jetty-http-9.3.0.M2.jar"
lib/dir1/org/eclipse/jetty/jetty-util/9.3.0.M2/jetty-util-9.3.0.M2.jar:
mkdir -p $(dir $#) && curl -o $# "http://central.maven.org/maven2/org/eclipse/jetty/jetty-util/9.3.0.M2/jetty-util-9.3.0.M2.jar"
lib/dir1/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar:
mkdir -p $(dir $#) && curl -o $# "http://central.maven.org/maven2/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar"
lib/dir1/org/slf4j/slf4j-api/1.7.10/slf4j-api-1.7.10.jar:
mkdir -p $(dir $#) && curl -o $# "http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.10/slf4j-api-1.7.10.jar"
how can I remove the prefix 'lib/dir1' in the curl URL to get a simple rule like:
$(addsuffix lib/dir1/,org/eclipse/jetty/jetty-http/9.3.0.M2/jetty-http-9.3.0.M2.jar org/eclipse/jetty/jetty-util/9.3.0.M2/jetty-util-9.3.0.M2.jar javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar org/slf4j/slf4j-api/1.7.10/slf4j-api-1.7.10.jar):
mkdir -p $(dir $#) && curl -o $# \
"http://central.maven.org/maven2/$(something $#)"
something like 'substring-after'...
Doesn't $(patsubst lib/dir1/%,%,$#) work?
I want to compile a program in a bash for loop. When I run the program from the command line it will compile but when I use qsub it doesn't compile.
Is there something I am missing?
Regards,
John
Bash File
#!/bin/bash
#$ -N runTest
#$ -m e
#$ -r y
cd /afs/crc.nd.edu/user/private/NDPICMCC/SAFECODE
thisDir="SAFECODE"
t=2000
originalGUILine="pres = 7.6E1"
oldGUILine="$originalGUILine"
GUIfile="GUIVars.f90"
for (( i = -3 ; i <= 1 ; i=i+1 ))
do
p="7.6E$i"
newGUILine="pres = $p"
sed -i "s/$oldGUILine/$newGUILine/g" "$GUIfile"
oldGUILine="$newGUILine"
make clean >& /dev/null
make 1D >& /dev/null
make 1D
./PressurePIC
cp "Anode_ele_eng.csv" "../results/T_${t}_P_${p}_Energies.csv"
done
sed -i "s/$oldGUILine/$originalGUILine/g" "$GUIfile"
makefile
CC=ifort
OPTIONS = -warn noalign -autodouble
PRNG = luxury.f90
MAIN = NDPIC1D.v0.f90 GUIVars.f90 GlobalVars.f90 StatisticalDistribution.f90 Emission.f90
TODO = ParticleInCell.f90 MonteCarloCollision.f90 Transformations.f90
EXE = PressurePIC
all:
#$(CC) $(PRNG) $(MAIN) $(TODO) -o $(EXE) $(OPTIONS)
1D:
#$(CC) $(PRNG) $(MAIN) $(TODO) -o $(EXE) $(OPTIONS)
2D:
#$(CC) $(PRNG) $(MAIN) $(TODO) -o $(EXE) $(OPTIONS)
clean:
#rm *.mod $(EXE)
run:
#./$(EXE)
info:
#echo $(EXE)
I'm not sure what flavour of qsub you are using so this may not help ...
Try including
#$ -V
at the start of your script. On some systems which process qsub it ensures that environment variables are exported from your environment to the environment in which the script eventually runs. These environments are not, generally, the same.
I am trying to get the basename of filenames in Makefile; but it always fails: basename command does not work.
Here is my code:
list = a.xlib b.lib
all:
for each_lib in $(notdir $(list)); \
do \
if [[ $$each_lib == *.xlib ]]; then \
*** Here I need to get the basename of $$each_lib to some variable, say base_lib *** \
cp -p $$base_lib-un.xlib ../../dist/lib/$$each_lib \
else \
cp -p $$each_lib ../../dist/lib/$$each_lib \
fi; \
done;
If we can create a variable with the value of basename of each file in list, that would be perfect.
Thanks.
$(basename ...) is a make function. It cannot operate on shell variables, because they are expanded later than make commands. You can use the shells $(...) substitution, but you have to double the dollar sign, so makefile does not interpret it as a function.
See if one of the following options does what you want:
list = a.xlib b.lib
libs = $(filter-out %.xlib,$(list))
xlibs = $(filter %.xlib,$(list))
V ?= #
allsh:
$(V)for each_lib in $(notdir $(libs)); do \
echo cp -p $$each_lib ../../dist/lib/$$each_lib; \
done;
$(V)for each_lib in $(notdir $(xlibs)); do \
base_lib="$$(basename $$each_lib .xlib)"; \
echo cp -p $$base_lib-un.xlib ../../dist/lib/$$each_lib; \
done;
xlibsstripped = $(patsubst %.xlib,%,$(xlibs))
allmake:
$(V)for each_lib in $(notdir $(libs)); do \
echo cp -p $$each_lib ../../dist/lib/$$each_lib; \
done;
$(V)for each_lib in $(notdir $(xlibsstripped)); do \
echo cp -p $$each_lib-un.xlib ../../dist/lib/$$each_lib.xlib; \
done;
Run with make allsh/allmake V= to see the commands being run.
If what you want to do is get the basenames, I'm surprised that basename doesn't work. (What version of Make are you using?) Note that it is a Make function, so it goes outside the rules:
list = a.xlib b.lib
BASES = $(basename $(list))
You can do it with other Make functions (note the colons):
list := a.xlib b.lib
list := $(patsubst %.lib,%,$(list))
list := $(patsubst %.xlib,%,$(list))
If what you really want to do is move the files and modify the names of the xlib files (a-un.xlib => .../a.xlib), there's an easier way:
targets := $(addprefix ../../dist/lib/,$(list))
all: $(targets)
../../dist/lib/%.lib: %.lib
mv $< $#
../../dist/lib/%.xlib: %-un.xlib
mv $< $#