You are not logged in.
Hello there,
I am currently writing an audio player for command line and I thought of publishing it to the AUR.
For learning purposes I wrote a little program which prints a short message.
I want to create a packet of this and install it to a dir where it would make more sense to be (than in my programming dir).
The code is compiled using a makefile and is working in the directory when I call it with './programname'.
I am able to create a packet using makepkg.
But however after installing it with 'pacman -U' I cant find my program.
Have I missed something?
Also if someone got a nice tutorial which explains how to do this I would be thankful.
Unfortunately it seems google is unable to help my.
Thanks in advance
torte
Last edited by torte (2016-10-15 18:18:00)
Offline
Hi and welcome to the Arch Linux Forums
Would you mind pasting your PKGBUILD? This would help us debug your issue.
Also, for finding out where a package's files are installed on the system, you can use
pacman -Ql <packagename>
(see also https://wiki.archlinux.org/index.php/Pa … databases).
Offline
First of all thanks for the quick response.
Here is the PKGBUILD file
# Maintainer: Lehmann, Torsten <anatas.torsten@gmx.de>
pkgname=pkgtest
pkgver=0.1
pkgrel=1
pkgdesc=""
arch=('any')
url=""
license=()
groups=()
depends=()
makedepends=()
optdepends=()
provides=()
conflicts=()
replaces=()
backup=()
options=()
install=
changelog=
source=($pkgname-$pkgver.tar.gz)
noextract=()
md5sums=('SKIP') #autofill using updpkgsums
# SKIP for not checking
build() {
# cd "$pkgname-$pkgver"
cd "$pkgname"
# ./configure --prefix=/usr
make
}
package() {
# cd "$pkgname-$pkgver"
cd "$pkgname"
make DESTDIR="$pkgdir/" install
}
And also my makefile:
CC = gcc
OBJ = pkg_test.c
.PHONY: install
install: $(OBJ)
$(CC) -o pkg_test $^
Also 'pacman -Ql <packetname>' does not print anything. Is my packet not installed?
Last edited by torte (2016-10-10 09:16:59)
Offline
Your makefile doesn't have any references to DESTDIR, so DESTDIR="$pkgdir/" will not have any effect.
If you want to write more useful makefiles, read https://www.gnu.org/prep/standards/html … onventions
However, if you're just wanting a quick and easy way to make a package, just use install to put the files in the right place during package().
e.g.
[...]
package() {
install -Dm755 "$srcdir/pkg_test" "$pkgdir/usr/bin/pkg_test"
}
[...]
Mod note: Moving to Creating and Modifying Packages.
EDIT:
Also 'pacman -Ql <packetname>' does not print anything. Is my packet not installed?
If you get no output, that means the package doesn't contain anything. If the package wasn't installed, you would get an error message, e.g. "error: package 'pkg_test' was not found"
Last edited by WorMzy (2016-10-10 11:27:26)
Sakura:-
Mobo: MSI MAG X570S TORPEDO MAX // Processor: AMD Ryzen 9 5950X @4.9GHz // GFX: AMD Radeon RX 5700 XT // RAM: 32GB (4x 8GB) Corsair DDR4 (@ 3000MHz) // Storage: 1x 3TB HDD, 6x 1TB SSD, 2x 120GB SSD, 1x 275GB M2 SSD
Making lemonade from lemons since 2015.
Offline
I second the comment to learn about writing proper Makefiles. Not only does your makefile lack what is needed to properly install the program, you use many conventions incorrectly. Having a Makefile missing some useful parts is not so bad, packagers can fill it in as needed, but please do not misuse conventions.
Most importantly, you have an "install" directive, but that does not install anything, that builds the program - this should definitely not be called "install". Generally this would be under a directive of the name of the program or under the directive "all:". The name of the program is useful as a directive as it doesn't need to be listed as a .PHONY.
Also, less problematic, but still a little odd is that OBJ is an abbreviation for object, but what it is set to is not an object file or list of objects, but rather a source file: object files are the .o intermediate compile products common when many modules are individually compiled before linking. You have a single source file, so you are rightly compiling and linking as a single step, but there is then no object file and OBJ is misleading.
Lastly, as the least important but still useful change, set CC only if it is not already defined:
CC ?= gcc
This way you let the user (or their system) decide which c compiler to use. Only use `CC = gcc` if you know your code will *only* work when compiled specifically with gcc.
"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" - Richard Stallman
Offline
First of all thanks for the quick response and the tips.
I am going to read more about creating makefiles and improving my skills this way.
Offline
Hello,
I have read a bit more about makefiles and how makpkg works and recreated my makefile and the PKGBUILD file.
Now it seems to work.
But how can I improve them further? Because to me it seems not well writen.
Makefile:
SHELL = /bin/sh
.SUFFIXES:
.SUFFIXES: .c
CC ?= gcc
INSTALL = install
SOURCE = pkg_test.c
TARGET = pkg_test
all: $(TARGET) $(SOURCE)
$(CC) -o $(TARGET) $(SOURCE)
.PHONY: install
install:
$(INSTALL) -Dm755 "$(TARGET)" "$(DESTDIR)"
.PHONY: clean
clean:
rm *.o
PKGBUILD:
# Maintainer: Lehmann, Torsten <anatas.torsten@gmx.de>
pkgname=pkgtest
pkgver=1.0
pkgrel=1
pkgdesc=""
arch=('any')
url=""
license=()
groups=()
depends=()
makedepends=()
optdepends=()
provides=()
conflicts=()
replaces=()
pkg_testup=()
options=()
install=
changelog=
source=($pkgname-$pkgver.tar.gz)
noextract=()
md5sums=('SKIP') #autofill using updpkgsums
# SKIP for not checking
pkgdir="../../pkg"
build() {
cd "$pkgname"
# ./configure --prefix=/usr
make
}
package() {
cd "$pkgname"
make DESTDIR="$pkgdir/usr/local/bin/$pkgname" install
}
Thanks in advance.
torte
Offline
These will indeed work together, but neither of them are "right" on their own - they just compensate for each other's wrongs.
Most notably, DESTDIR should not be the final destination of a specific file, it is the target root directory. As such the Makefile should not depend on DESTDIR actually being set. See one of my Makefiles here:
https://raw.githubusercontent.com/Trilb … r/Makefile
This Makefile will work with a PKGBUILD which sets a DESTDIR (like this one for that package). But the Makefile would work prefectly well for another distro where someone just run `make` and `make install`. If DESTDIR is not set, all the content is installed under $PREFIX, and if PREFIX is not explicitly set then it defaults to /usr/, so if neither DESTDIR nor PREFIX is set by the user/packager then everything is installed under /usr/ which is where it should be (e.g. /usr/bin, /usr/share, etc).
In your case, you've assumed DESTDIR to be not a DESTination DIRectory for the package content, but the exact filename of the executable. And if DESTDIR is not explicitly set, your Makefile will completely fail to install anything.
Also, TARGET should not be listed as a requirement for making TARGET. That directive actually fails completely, just coincidentally make's implicit rules cover for you. But TARGET should be a requirement for the install directive.
Lastly, your clean directive does nothing: you have no object files to remove, unless it's because the implicit rules create them in which case your other rules are superfluous.
EDIT: I hadn't actually looked closely at the PKGBUILD - do not try to set pkgdir. I'm pretty sure that is ignored/overridden by Makepkg anyways so you can't do any harm, but trying to set it will either do nothing, or do harm. Also get rid of all the empty variables/arrays. Source will have to be url when submitted to the AUR. Please look at some example PKGBUILDs and the Makefiles for their projects in the AUR.
"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" - Richard Stallman
Offline
Your makefile and PKGBUILD really helped me see the wrong parts in mine.
Therefore I would like to thank you.
I updated the makefile:
CC ?= gcc
PROG = pkg_test
SRC = pkg_test.c
PREFIX ?= /usr
all: $(PROG)
$(PROG): $(SRC)
$(CC) -o $@ $^
install: all
@install -Dm755 $(PROG) $(DESTDIR)$(PREFIX)/bin/$(PROG)
clean:
rm $(PROG)
aswell as my PKGBUILD:
# Maintainer: Lehmann, Torsten <anatas.torsten@gmx.de>
pkgname=pkgtest
pkgver=1.0
pkgrel=1
arch=('any')
url=""
source=($pkgname-$pkgver.tar.gz)
md5sums=('SKIP') #autofill using updpkgsums
# SKIP for not checking
build() {
make
}
package() {
make PREFIX=/usr DESTDIR="$pkgdir" install
}
Both are working fine and are hopefully written in the wright way by now.
Torte
Last edited by torte (2016-10-15 17:43:20)
Offline
They look great now. As a minor point, there are conventions for what "clean" and similar directives in Makefiles do. Normally "clean" is expected to remove any regeneratable files *except* for the final product (object files for example). Your clean directive removes the final binary product. This is not a problem, but a directive to do this would more often be called "moreclean" or "distclean".
"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" - Richard Stallman
Offline