You are not logged in.

#1 2016-10-10 08:41:28

torte
Member
From: Freiberg (Sachs.), Germany
Registered: 2016-10-09
Posts: 5

[SOLVED] How to publish a program

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

#2 2016-10-10 08:57:54

ayekat
Member
Registered: 2011-01-17
Posts: 1,590

Re: [SOLVED] How to publish a program

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).


pkgshackscfgblag

Offline

#3 2016-10-10 09:16:01

torte
Member
From: Freiberg (Sachs.), Germany
Registered: 2016-10-09
Posts: 5

Re: [SOLVED] How to publish a program

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

#4 2016-10-10 11:25:18

WorMzy
Forum Moderator
From: Scotland
Registered: 2010-06-16
Posts: 11,868
Website

Re: [SOLVED] How to publish a program

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

#5 2016-10-10 11:38:34

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,534
Website

Re: [SOLVED] How to publish a program

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

#6 2016-10-10 21:54:17

torte
Member
From: Freiberg (Sachs.), Germany
Registered: 2016-10-09
Posts: 5

Re: [SOLVED] How to publish a program

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

#7 2016-10-11 09:46:00

torte
Member
From: Freiberg (Sachs.), Germany
Registered: 2016-10-09
Posts: 5

Re: [SOLVED] How to publish a program

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

#8 2016-10-11 11:30:26

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,534
Website

Re: [SOLVED] How to publish a program

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

#9 2016-10-15 17:40:59

torte
Member
From: Freiberg (Sachs.), Germany
Registered: 2016-10-09
Posts: 5

Re: [SOLVED] How to publish a program

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

#10 2016-10-15 18:00:08

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,534
Website

Re: [SOLVED] How to publish a program

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

Board footer

Powered by FluxBB