You are not logged in.
I am new to this community, and in Arch Linux in general, so please bear with me.
I'm looking for something like a standard way of accessing PKGBUILD metadata within the .INSTALL script. The usual .SRCINFO is generated in a "key = value" pair, but somehow I can't just source the file in bash to access the variables. Is there a proper way of doing this?
Last edited by ItsMeKuroro (2020-02-16 01:30:37)
Offline
Offline
What are you trying to do in your .INSTALL script?
First, thank you for your reply!
This is unrelated, but I'm actually using the pacman version of MSYS2. Anyways, I would like to create a windows symlink in the .INSTALL script's post_install() function, coz creating one in the PKGBUILD's package() function does not properly bundle the symbolic link, i.e, the final *.pkg.tar.xz treats the shortcut as just another copy of the target (here is the GitHub issue).
But I would also like to access some of the PKGBUILD metadata, specifically the $pkgname and $pkgver to point to the correct directory.
Here's my .INSTALL script example:
post_install() {
export MSYS=winsymlinks:nativestrict
ln -s "/opt/${pkgname}/${pkgver}/" "/opt/${pkgname}/default"
}
post_remove() {
rm "/opt/${pkgname}/default"
}Offline
The pkgname is known in advanced so why not store it at the top of the .install file?
In case you do not have access to the PKGBUILD man page https://jlk.fjfi.cvut.cz/arch/manpages/man/PKGBUILD.5
The argument to post_install and post_remove will be the package version.
pkgname=name
post_install() {
export MSYS=winsymlinks:nativestrict
ln -s "/opt/$pkgname/$1/" "/opt/$pkgname/default"
}
post_remove() {
rm "/opt/$1/default"
}Offline
The pkgname is known in advanced so why not store it at the top of the .install file?
In case you do not have access to the PKGBUILD man page https://jlk.fjfi.cvut.cz/arch/manpages/man/PKGBUILD.5
The argument to post_install and post_remove will be the package version.pkgname=name post_install() { export MSYS=winsymlinks:nativestrict ln -s "/opt/$pkgname/$1/" "/opt/$pkgname/default" } post_remove() { rm "/opt/$1/default" }
I'm aware of that. But is this the common way to do it? I'm thinking that the $pkgname is already defined in the PKGBUILD, so why not use that instead? The package version is actually the $pkgver and $pkgrel (correct me if I'm wrong), but I only need the exact $pkgver coz it is part of the main archive source when it is extracted.
I tried something like a variable injection to .INSTALL script before it is added, but it is an overkill I guess:
test.install
post_install() {
ln -s "/opt/<pkgname>/<pkgver>/" "/opt/<pkgname>/default"
}
post_remove() {
rm "/opt/<pkgname>/default"
}PKGBUILD
pkgname='test'
pkgver=0.0.0
install="${pkgname}.install"
# ...
package() {
# inject $pkgname and $pkgver to .INSTALL script
sed -i.bak "s/<pkgname>/${pkgname}/g;s/<pkgver>/${pkgver}/g" "${startdir}/${pkgname}.install"
}
# restore backup .INSTALL script
trap "[ -f ${startdir}/${pkgname}.install.bak ] && mv ${startdir}/${pkgname}.install.bak ${startdir}/${pkgname}.install" EXITIs there any other way to achieve this? I'm looking for a proper way to do this...
Offline
The linux package in the past used an install script that was modified by the PKGBUILD
https://git.archlinux.org/svntogit/pack … 7dcac16952
Offline
The linux package in the past used an install script that was modified by the PKGBUILD
https://git.archlinux.org/svntogit/pack … 7dcac16952
Thank you very much! That solved the issue I guess ![]()
Offline
I'm aware of that. But is this the common way to do it? I'm thinking that the $pkgname is already defined in the PKGBUILD, so why not use that instead? The package version is actually the $pkgver and $pkgrel (correct me if I'm wrong), but I only need the exact $pkgver coz it is part of the main archive source when it is extracted.
Close -- it is the "fullpkgver", which is composed of 3 parts, defined by the following pseudocode:
retval = ""
# part 1
if exists(epoch):
retval += epoch
retval += ":"
# part 2
retval += pkgver
retval += "-"
# part 3
retval += pkgrel
print(retval)See the official bash/makepkg function that prints this: https://git.archlinux.org/pacman.git/tr … 5.2.1#n161
The C version in pacman/libalpm for parsing it is here: https://git.archlinux.org/pacman.git/tr … c?h=v5.2.1
It is easily split, since none of the 3 components may contain a colon or hyphen, so you can strip off the one (1) hyphen in the passed value, along with all characters following it, and, if there is a colon, also remove the colon and any preceding characters.
(In fact, the first component must be an unsigned integer, and the third component must be either an unsigned integer or an unsigned decimal.)
If you do not want to do this simple parsing, you will need to use the the install script sed in package(), but I would advise parsing the function argument.
Last edited by eschwartz (2020-02-16 01:40:09)
Managing AUR repos The Right Way -- aurpublish (now a standalone tool)
Offline
...
If you do not want to do this simple parsing, you will need to use the the install script sed in package(), but I would advise parsing the function argument.
Thank you. I will note all that ![]()
Another thing is, since the only script that is executed is the PKGBUILD, I think it is the only appropriate way to just handle everything inside it, just like what loqs posted:
The linux package in the past used an install script that was modified by the PKGBUILD
https://git.archlinux.org/svntogit/pack … 7dcac16952
I also have other scripts, like profile.d scripts, that I wanted to have access to some long metadata defined in PKGBUILD, so I guess I'll stick to the sed command at the moment...
Offline
The problem is that the install script is one of the source files distributed with the PKGBUILD, so running sed on it will permanently modify the file which you use to build future packages. It no longer contains your <pkgname> and <pkgver> identifiers.
If you happen to be using git for this, you could recover by running git checkout HEAD . to reset all files back to their committed versions... I don't think this is even remotely clean in the slightest.
The linux PKGBUILD which you were linked to used a loophole to do delayed evaluation: https://git.archlinux.org/svntogit/pack … 16952#n108
This resulted in the install file used during package() being different from the one which is reported in the .SRCINFO or linted, and that temporary file is the one which was outputted by sed.
Managing AUR repos The Right Way -- aurpublish (now a standalone tool)
Offline
The problem is that the install script is one of the source files distributed with the PKGBUILD, so running sed on it will permanently modify the file which you use to build future packages. It no longer contains your <pkgname> and <pkgver> identifiers.
If you happen to be using git for this, you could recover by running git checkout HEAD . to reset all files back to their committed versions... I don't think this is even remotely clean in the slightest.
The linux PKGBUILD which you were linked to used a loophole to do delayed evaluation: https://git.archlinux.org/svntogit/pack … 16952#n108
This resulted in the install file used during package() being different from the one which is reported in the .SRCINFO or linted, and that temporary file is the one which was outputted by sed.
Yep, you are correct! I just realized it while editing my sources ![]()
So we should just copy/paste all the metadata from PKGBUILD since they are already known? The problem with this is, it would result to a lot of work for long scripts...
Here are all the sources I'm currently working with, it's just a Gradle distribution for Windows:
PKGBUILD
pkgname='gradle'
pkgver=6.1.1
pkgrel=1
pkgdesc='A powerful build system for the JVM'
arch=('i686' 'x86_64')
url='https://gradle.org'
license=('Apache')
options=('!makeflags')
install="${pkgname}.install"
source=("https://services.gradle.org/distributions/${pkgname}-${pkgver}-all.zip"
"${pkgname}.csh"
"${pkgname}.sh")
sha256sums=('10065868c78f1207afb3a92176f99a37d753a513dff453abb6b5cceda4058cda'
'SKIP'
'SKIP')
package() {
# TODO: Handle .INSTALL script and profile.d scripts here
install -d "${pkgdir}/opt/${pkgname}"
cp -a "${pkgname}-${pkgver}" "${pkgdir}/opt/${pkgname}"
mv "${pkgdir}/opt/${pkgname}/${pkgname}-${pkgver}" "${pkgdir}/opt/${pkgname}/${pkgver}"
install -Dt "${pkgdir}/etc/profile.d" "${pkgname}.csh" "${pkgname}.sh"
}gradle.install
post_install() {
export MSYS=winsymlinks:nativestrict
rm -f "/opt/<pkgname>/default"
ln -s "/opt/<pkgname>/<pkgver>" "/opt/<pkgname>/default"
}
post_remove() {
rm "/opt/<pkgname>/default"
}gradle.csh
setenv GRADLE_HOME "/opt/<pkgname>/default"
setenv PATH "${PATH}:${GRADLE_HOME}/bin"gradle.sh
export GRADLE_HOME="/opt/<pkgname>/default"
export PATH="${PATH}:${GRADLE_HOME}/bin"I know this is just a small package build, but I would also like to apply the same approach for larger package builds...
So the question remains, how to properly access PKGBUILD metadata for other sources?
Offline
Well, for any file that is installed to $pkgdir you can edit it with sed in the PKGBUILD during the package() phase, once it is installed to $pkgdir (or even use mkdir -p "$pkgdir"/etc/profile.d; sed 's///' foo.sh > "$pkgdir"/etc/profile.d/foo.sh to install it using sed itself).
The issue is specifically with the install= and changelog= files, since those aren't really "source" files and don't get installed to $pkgdir.
But the issue primarily gets discovered with install= files -- and as already mentioned in the thread, you can programmatically get the pkgver from the post_install/post_upgrade arguments instead of using sed. Setting the pkgname alone is fairly manageable since it only needs to happen once when initially creating the package -- you can even define it at the top of the file, and use a shared template for the rest of the file.
Last edited by eschwartz (2020-02-16 03:15:16)
Managing AUR repos The Right Way -- aurpublish (now a standalone tool)
Offline
Well, for any file that is installed to $pkgdir you can edit it with sed in the PKGBUILD during the package() phase, once it is installed to $pkgdir (or even use mkdir -p "$pkgdir"/etc/profile.d; sed 's///' foo.sh > "$pkgdir"/etc/profile.d/foo.sh to install it using sed itself).
The issue is specifically with the install= and changelog= files, since those aren't really "source" files and don't get installed to $pkgdir.
But the issue primarily gets discovered with install= files -- and as already mentioned in the thread, you can programmatically get the pkgver from the post_install/post_upgrade arguments instead of using sed. Setting the pkgname alone is fairly manageable since it only needs to happen once when initially creating the package -- you can even define it at the top of the file, and use a shared template for the rest of the file.
Thank you so much for all the info sir! I'm wrapping my thoughts and figure this one out
I'll edit my original post to include the methods I came up with.
Offline