I want to create a Debian package from a C program without the use of a build tool such as autotools or CMake. My debian/rules file:
#!/usr/bin/make -f
%:
dh $#
override_dh_auto_clean:
rm -f program
override_dh_auto_build:
gcc program.c -o program
override_dh_auto_install:
cp program /usr/local/bin
Upon running dpkg-buildpackage, I get:
dh: error: Unknown sequence application (choose from: binary binary-arch binary-indep build build-arch build-indep clean install install-arch install-indep)
It seems the issue was related to the fact that I was creating the file in a shell script heredoc that was expanding the $#, e.g.
cat <<EOF > debian/rules.temp
#!/usr/bin/make -f
%:
dh $#
EOF
Which should be:
all_symbol='$#'
cat <<EOF > debian/rules.temp
#!/usr/bin/make -f
%:
dh $all_symbol
EOF
An unrelated issue is to the location of the override_dh_auto_install To manually create Debian file hierarchy it should be:
override_dh_auto_install:
mkdir -p debian/PACKAGENAME/usr/bin
cp program debian/PACKAGENAME/usr/bin
Or, to have this done automatically:
cat <<EOF > debian/PACKAGENAME.install
program usr/bin
EOF
Related
I am running a program (OpenModelica OMEdit 1.18.0~dev-109-ged8ef0a) which requires gmake for one of its operations. gmake is not installed on my Mac (Big Sur 11.5.2) but make is. I tried to symlink gmake to point at make but it does not work:
➜ where make
/usr/bin/make
➜ make -v | HEAD -n 1
GNU Make 3.81
➜ pwd
/opt/openmodelica/bin
➜ sudo ln -s /usr/bin/make /opt/openmodelica/bin/gmake
➜ ls -lh gmake
lrwxr-xr-x 1 root wheel 13B 13 Dec 09:15 gmake -> /usr/bin/make
➜ /opt/openmodelica/bin/gmake -v
gmake: error: sh -c '/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -find gmake 2> /dev/null' failed with exit code 17664: (null) (errno=Invalid argument)
xcode-select: Failed to locate 'gmake', requesting installation of command line developer tools.
It prompts each time to install the XCode command line developer tools which I have already done. From the error message it looks like it is trying to find gmake despite pointing at the make executable? (Why is it erroring?) Is there a way to get this to work as I was expecting or do I have to install gmake using brew then symlink to that?
Command line tools version:
➜ pkgutil --pkg-info=com.apple.pkg.CLTools_Executables
package-id: com.apple.pkg.CLTools_Executables
version: 12.5.1.0.1.1623191612
volume: /
location: /
install-time: 1639360537
groups: com.apple.FindSystemFiles.pkg-group
** edit **
I'm using zsh 5.8 (x86_64-apple-darwin20.0), I don't know if that's a factor in the gmake symlink to make not working correctly?
I don't understand why this works but from #Holger Just's comment:
➜ brew install make
This will add a symlink:
➜ ls -lh /usr/local/bin/gmake
/usr/local/bin/gmake# -> ../Cellar/make/4.3/bin/gmake
And then symlinking to that instead:
➜ sudo ln -s /usr/local/bin/gmake /opt/openmodelica/bin/gmake
... works as expected:
➜ /opt/openmodelica/bin/gmake -v | head -n 1
GNU Make 4.3
Here's my Makefile:
dist/%.js: src/%.js node_modules
$(NM)/babel $< -o $#
build: $(patsubst src/%,dist/%,$(wildcard src/**/*.js))
It runs a command like this:
node_modules/.bin/babel src/deep/foo.js -o dist/deep/foo.js
The problem is that if dist/deep doesn't exist, it errors:
Error: ENOENT: no such file or directory, open 'dist/deep/foo.js'
So what I want to do is add an extra dependency on the directory, which I was hoping I could do with something like this:
dist/%.js: src/%.js $(dir dist/%) node_modules
$(NM)/babel $< -o $#
dist/%/:
mkdir -p $#
build: $(patsubst src/%,dist/%,$(wildcard src/**/*.js))
But it doesn't work. $(dir dist/%) isn't filling in that % like I hoped. Running make --trace yields:
Makefile:10: update target 'dist/deep/foo.js' due to: src/deep/foo.js dist/ node_modules
i.e., you can see it has a dependency on dist/, but I was hoping it'd depend on dist/deep/ so that I could mkdir -p it.
Is there a way to achieve what I want?
First a subsidiary snag. Judging from:
$(wildcard src/**/*.js)
it seems you want this function to perform recursive globbing,
returning all *.js files that exist in src or any subdirectory
thereof.
I don't know what shell you've got, but they don't all do that by
default. The linux bash shell doesn't, though as of bash 4.0
it will do it if the shell option globstar is set.
And anyway, $(wildcard ...) won't do it (unless, possibly, the
operative shell does it by default, which I'm not in a position to
check out). So you can't dependably use $(wildcard ...) for that
purpose. You need make to be invoking a shell in which recursive
** globbing is enabled, and then call:
$(shell ls src/**/*.js)
So that's what I'll do now in showing how to solve your problem with
a simple example. I've got:
src/
one.js
a/
two.js
c/
four.js
b/
three.js
and I just want to each *.js file copied from beneath src to the
same relative name under dist, ensuring that dist and all
necessary subdirectories exist when required to. (Of course, this
could all be done at once with cp). Here is a makefile:
SHELL := /bin/bash
.SHELLFLAGS := -O globstar -c
SRCS := $(shell ls src/**/*.js)
DISTS := $(patsubst src/%,dist/%,$(SRCS))
DESTDIRS := $(dir $(DISTS))
.PHONY: all clean
all: $(DISTS)
dist/%.js: src/%.js | $(DESTDIRS)
cp $< $#
$(DESTDIRS):
mkdir -p $#
clean:
rm -fr dist
which runs like:
$ make
mkdir -p dist/a/c/
mkdir -p dist/b/
cp src/a/c/four.js dist/a/c/four.js
cp src/a/two.js dist/a/two.js
cp src/b/three.js dist/b/three.js
cp src/one.js dist/one.js
In that makefile,
| $(DESTDIRS)
makes each of the $(DESTDIRS) an order-only prerequisite
of any target dist/%.js. An order-only prequisite is not considered in determining whether its
target shall be made, but if it is determined that the target shall be made, then the
order-only prequisite will be made first.
I have a makefile (below) for a project where I've been given a folder of "Raw Data" - a set of files from a colleague, and I've made an R script that does an analysis on some of those files. What I want to do with a the makefile then is assign the directory to a variable RAWDIR, and then use that variable in specifying the make dependencies of the R script, and as a command line argument for the script. Usually in the shell, directories with spaces are expanded when using double quotes and curly braces, but I do not know if this is also correct for make files, as with the following makefile I get the message make: *** No rule to make target""../Raw', needed by pulls'. Stop. So I do not think my file path assigned to RAWDIR is being expanded properly.
Thanks.
RAWDIR="../Raw Data/Fc Project Raw Data"
.PHONY: dirs
pulls: dirs "${RAWDIR}/pm_fc_dnds_cleandata.csv" "${RAWDIR}/fc1_seqs.fasta" "${RAWDIR}/fc2_seqs.fasta" "${RAWDIR}/pm1_seqs.fasta" "${RAWDIR}/pm2_seqs.fasta"
Rscript Allele_Pulling.R "${RAWDIR}/" "${RAWDIR}/pm_fc_dnds_cleandata.csv"
dirs:
mkdir -p -v Pulled_Allelic_Pairs/Unaligned/FC
mkdir -p -v Pulled_Allelic_Pairs/Unaligned/PM
mkdir -p -v Pulled_Allelic_Pairs/Unaligned/Both
mkdir -p -v Pulled_Allelic_Pairs/Unaligned/FC1PM1
mkdir -p -v Pulled_Allelic_Pairs/Unaligned/FC1PM2
mkdir -p -v Pulled_Allelic_Pairs/Unaligned/FC2PM1
mkdir -p -v Pulled_Allelic_Pairs/Unaligned/FC2PM2
mkdir -p -v Pulled_Allelic_Pairs/Aligned/FC
mkdir -p -v Pulled_Allelic_Pairs/Aligned/PM
mkdir -p -v Pulled_Allelic_Pairs/Aligned/Both
mkdir -p -v Pulled_Allelic_Pairs/Aligned/FC1PM1
mkdir -p -v Pulled_Allelic_Pairs/Aligned/FC1PM2
mkdir -p -v Pulled_Allelic_Pairs/Aligned/FC2PM1
mkdir -p -v Pulled_Allelic_Pairs/Aligned/FC2PM2
In general spaces in pathnames are not well supported by make. At least some functions in GNU make could handle spaces that are escaped by \.
The following should work in your use case:
RAWDIR="../Raw\ Data/Fc\ Project\ Raw\ Data"
I'm using the console of PDFSam to split and merge some PDF files. I can do this semi-automatically using .bat files, but I would like to do the whole thing in R.
This code in my .bat file works:
C:
cd "/Program Files/pdfsam/bin/"
run-console.bat -f "d:/delete/A_9.pdf" -o d:/delete -s BURST -overwrite split
But this "equivalent" code in my R shell command returns no errors, but doesn't seem to work.
shell('C:
cd "/Program Files/pdfsam/bin/"
run-console.bat -f "d:/delete/A_9.pdf" -o d:/delete -s BURST -overwrite split')
Is there an option I'm missing in my shell command? I've tried a few of the options listed in ?shell to no avail.
I'm using windows XP and
R version 2.13.1 (2011-07-08)
Platform: i386-pc-mingw32/i386 (32-bit)
Thanks,
Tom
You could pass multiple commands to shell by concatenating them by &, so below should work:
shell('C: & cd C:/Program Files/pdfsam/bin & run-console.bat -f "d:/delete/A_9.pdf" -o d:/delete -s BURST -overwrite split')
But as a workaround you could temporary change R working directory:
current.wd <- getwd()
setwd("C:/Program Files/pdfsam/bin")
shell('run-console.bat -f "d:/delete/A_9.pdf" -o d:/delete -s BURST -overwrite split')
setwd(current.wd)
If you do it frequent write a function:
shell.in.dir <- function(dir, ...) {
current.wd <- getwd()
on.exit(setwd(current.wd))
setwd(dir)
shell(...)
}
shell.in.dir("C:/Program Files/pdfsam/bin",
'run-console.bat -f "d:/delete/A_9.pdf" -o d:/delete -s BURST -overwrite split')
This isn't exactly an answer to your question, but you might try system("youBatFile.bat") as an alternative.
I would like in my GNUmakefile to have a target rule that invokes a new shell and then with the clean slate of the new shell invokes a new make.
What is the syntax to do this?
I tried this but it didn't work:
.PHONY: setup
setup:
shell cd myDir; make; cd ..
It gets infinite repeat of the following error:
make[1]: Entering directory `/disk4/home/user/parent'
shell cd myDir; make; cd ..
/bin/sh: shell: command not found
make[1]: Entering directory `/disk4/home/user/parent'
shell cd myDir; make; cd ..
/bin/sh: shell: command not found
[...]
(cd myDir ; make)
The parens invoke a new subshell, with its own "current directory".
The parens are not necessary. Every line in a recipe is invoked in its own shell anyway. Your recipe seems to have a superfluous shell string, which your shell tries to execute as a command (/bin/sh (your shell, not make) complains shell: command not found).
Also, make's -C parameter is handy in this case.
Also, when calling make from the shell, use the ${MAKE} macro.
.PHONY: setup
setup:
unset MAKEFLAGS; ${MAKE} -C myDir
Here is what works:
.PHONY: setup
setup:
(cd myDir; env --unset=MAKEFLAGS make)