# building a binary package for multiple versions of FreeBSD



## Xylene (Feb 28, 2018)

Is there a way to use pkg create to build a binary package that can be installed on multiple versions of FreeBSD. i.e 10.X (latest release) and 11.x (latest release) without having to use the pkg add/install -f flag?


----------



## asteriskRoss (Feb 28, 2018)

Welcome to the forums, Xylene.  You could use Poudriere (available as the port sysutils/poudriere) to build multiple versions of your package, each targeted at a different version of FreeBSD and also for each of the i386 and amd64 architectures if needed.


----------



## Xylene (Feb 28, 2018)

I would really like to find a way to build a single binary package that works on multiple versions of FreeBSD.  As a 3rd party software vendor I don't want to have to maintain multiple packages for a single OS if not needed. I can build a single RPM package on RHEL 4 and have it work on RHEL 4,5,6 and 7 as well as Suse, Fedora, CentOS (Any system that uses rpm as it's package manager) but with pkg, I am forced to only use it on the system it was built on.


----------



## asteriskRoss (Feb 28, 2018)

I understand what you want to do and why, though unfortunately I don't think it's possible.  However, I would suggest also asking on the freebsd-pkg mailing list.

Do consider sysutils/poudriere, particularly if you were planning to provide your software via a package repository.  As long as your build machine is running the latest version of FreeBSD you want to support you can build (and test) all versions on that single machine.  The process is easily automated.  With three versions of FreeBSD currently supported (10.3, 10.4 and 11.1) perhaps the effort to maintain multiple packages won't be as significant as you fear.


----------



## drhowarddrfine (Mar 1, 2018)

This is a bit unclear. If you mean binaries that run on 32-bit and 64-bit, you may be mistaken about RPM's abilities. Ditto if you mean running the same binaries written for RHEL 7 to run on RHEL 4. Any binary that does not have hardware or version requirements or ABI differences, created for pkg, will run on any version of FreeBSD but, as I said, your question isn't entirely clear.


----------



## Xylene (Mar 1, 2018)

drhowarddrfine said:


> This is a bit unclear. If you mean binaries that run on 32-bit and 64-bit, you may be mistaken about RPM's abilities. Ditto if you mean running the same binaries written for RHEL 7 to run on RHEL 4. Any binary that does not have hardware or version requirements or ABI differences, created for pkg, will run on any version of FreeBSD but, as I said, your question isn't entirely clear.



I specifically mean I can create a 64bit rpm package on RHEL 4 and install that same package on any OS that uses rpm and is 64bit. (and meets the dependencies criteria) I want that same functionality in FreeBSD. I want to build a 64bit package on FreeBSD 10 and have it work on FreeBSD11 as well.

Is there a way to do this?


----------



## SirDice (Mar 1, 2018)

For starters, in order to run FreeBSD 10 binaries on a FreeBSD 11 system you would need misc/compat10x and the COMPAT_FREEBSD10 kernel option (GENERIC has this by default).

Are we talking about real binaries? I.e. compiled executables as opposed to scripts? Are these linked to other libraries, most notably libc? Or are they statically linked?


----------



## Lamia (Mar 1, 2018)

SirDice said:


> For starters, in order to run FreeBSD 10 binaries on a FreeBSD 11 system you would need misc/compat10x and the COMPAT_FREEBSD10 kernel option (GENERIC has this by default).
> 
> Are we talking about real binaries? I.e. compiled executables as opposed to scripts? Are these linked to other libraries, most notably libc? Or are they statically linked?


Xylene: You would still need try poudriere. It can setup a FreeBSD10 jail on FreeBSD11 host, fetch the ports for the FreeBSD10 and build your choice packages in it. You will then install the compat10x pkg (as advised by SirDice) on the host you want to install the built packages on before you install the built pkgs.


----------



## Xylene (Mar 1, 2018)

lamia said:


> Xylene: You would still need try poudriere. It can setup a FreeBSD10 jail on FreeBSD11 host, fetch the ports for the FreeBSD10 and build your choice packages in it. You will then install the compat10x pkg (as advised by SirDice) on the host you want to install the built packages on before you install the built pkgs.



Yes they are real binaries, and yes they are linked to other libraries.  The lib dependencies is not an issue, the only problem I have is that when I build a binary package on FreeBSD 10 and attempt to install the same package on FreeBSD 11, pkg fails with:

pkg:wrong architecture: FreeBSD:10:amd64 instead of FreeBSD:11:amd64

but if I run pkg install -f <package> and force the install, then everything installs and works as expected.

Is there a way to create the package so that pkg doesn't complain/fail when I attempt to install it on a newer version of FreeBSD?  I know I can use poudriere to create jails on my build machine, but I would really like to not have to generate multiple packages to support different version of FreeBSD, especially when all other OS's that I build packages on do not have this same requirement when the underlying arch is the same. RPM is the perfect example of this. I build my product on RHEL 4 x86_64 and the generated rpm can now be used on any x86_64 os that uses rpm and has the same or higher kernel level (plus accompanying linked libs like libc)


----------



## Xylene (Mar 7, 2018)

I am going to take the silence as pkg isn't intelligent enough to handle this situation.


----------



## Lamia (Mar 8, 2018)

Xylene said:


> Is there a way to create the package so that pkg doesn't complain/fail when I attempt to install it on a newer version of FreeBSD?


Hoping that there is no change in its dependencies, you will need rebuild it for the OS version bumping up its DISTVERSION and/or PORTREVISION.

You might also find this thread helpful.


----------



## Xylene (Mar 8, 2018)

The part I don't understand is why there is a package dependency on the OS version, why is the package dependency not just on the arch? I have never seen another package manager complain about the version of the OS it is installing the package on.  Why does pkg care that the OS is FreeBSD:11:amd64 instead of FreeBSD:10:amd64 if all dependencies are on the box? This seems like a bug in the code to me.


----------



## SirDice (Mar 8, 2018)

Xylene said:


> The part I don't understand is why there is a package dependency on the OS version, why is the package dependency not just on the arch?


Because you're depending on libraries with a certain ABI version. The ABI can be different between two major versions. And while it apparently works for _your_ application there's no guarantee it'll work for _every_ application. And it apparently works for your application on 10.x and 11.x, there's no guarantee it's going to work for 12.x or 13.x.



Xylene said:


> Why does pkg care that the OS is FreeBSD:11:amd64 instead of FreeBSD:10:amd64 if all dependencies are on the box? This seems like a bug in the code to me.


You're looking at it the wrong way, it's not a bug. It's intentionally done in order to prevent issues with people trying to install old binaries on a later version with an incompatible ABI. And then complaining the package manager is broken because it allowed them to install something that's incompatible.


----------



## Xylene (Mar 12, 2018)

It sounds great and all, but yet somehow every enterprise level package manager is capable of such a thing. Could you imagine if RPM decided to behave this way? I would have to make 5 or more separate packages just to ship a product that supported RHEL 64, let alone all of the other distros that support rpm.


----------



## sko (Mar 13, 2018)

I think the main reason for your confusion is the fact, that the linux ABI (and API) has been in rigor mortis since almost a decade - i.e. they haven't changed for kernel <-> userspace interaction. Some small things have been added, but everything that was ever added to the ABI is still there (no matter how broken...). So you can still run ancient binaries on a current linux kernel because from the binaries viewpoint essentially nothing has changed.

On _any_ other OS (All UNIXes, Solaris, BSDs etc as well as Windows), the ABI evolves, hence the binaries need to be compatible (i.e. recompiled) to each specific ABI version. 
Some OS (e.g. Windows) have compatibility-layers installed and active by default and completely hide the fact that they emulate old ABI behaviour for some binaries. On FreeBSD you can just install the already mentioned 'compat' packages to get a similar effect.


----------



## ShelLuser (Mar 13, 2018)

Xylene said:


> It sounds great and all, but yet somehow every enterprise level package manager is capable of such a thing.


And so is pkg, you said so yourself: you only need to use the -f parameter. I'm having a bit of a hard time understanding why that would be a problem here.


----------



## Xylene (Apr 9, 2018)

The solution is when setting the abi just use

abi: *

Or in my case I wanted FreeBSD on amd64

abi: FreeBSD:*:amd64

Worked like a charm.


----------

