packager is sorrounding us (bug?)

I think I’ve found a bug in packager.
Let’s have an example:

  • I create a sample xpackage.qpk file from a qpm file.
    In the qpm file I add this line:

<QPG:Add file=“phscrslib/src/x86/so/libphscrslib.so”
install="/usr/photon/lib/libphscrslib.so.1" component=“slib”/>

As you can see, I change the name of the so to a .so.1 file.
If I leave .so ONLY everything goes fine. But when I specify a .so.1 file I
have to use component=“slib”. But (…) if I specify component=“slib”
packager generates not one, but TWO slib packages:

one called slib, and the other one called slib-slib:

------File Analysis------

Sorting files into the required packages.
Creating the directory structure.
Copying files to be packaged…OK
Adding scripts and repository data.

The following packages have been detected:
“phscrs” is the CPU-independent package.
“phscrs-host_x86” is the x86-specific package.
“phscrs-dev” is the CPU-independent package of “dev”.
“phscrs-dev-target_x86” is the CPU-independent package of
“dev” for developing x86 code.
“phscrs-slib” is the CPU-independent package of “slib”.
“phscrs-slib-host_x86” is the x86-specific package of “slib”.
“phscrs-slib-slib” is the CPU-independent package of “slib-slib”.
“phscrs-slib-slib-host_x86” is the x86-specific package holding
just the shared library files of “slib”.

Ok, what’s the need of generating a package holding just the shared
libraries when slib ALREADY contains the same library.
slib and slib-slib are identical.
Packager here seems to recognize slib as a new package, not the
“slib” package (unless I’m doing something wrong and slib package
is referred to something else).

Bests


Wave++

Wave++ <wavexx@apexmail.com> wrote:

I think I’ve found a bug in packager.
Let’s have an example:

  • I create a sample xpackage.qpk file from a qpm file.
    In the qpm file I add this line:

s/xpackage.qpk/xpackage.qpm
s/In the qpm/In the qpg

sorry, I was confused :slight_smile:

QPG:Add file=“phscrslib/src/x86/so/libphscrslib.so”
install="/usr/photon/lib/libphscrslib.so.1" component=“slib”/

As you can see, I change the name of the so to a .so.1 file.
If I leave .so ONLY everything goes fine. But when I specify a .so.1 file I
have to use component=“slib”. But (…) if I specify component=“slib”
packager generates not one, but TWO slib packages:

one called slib, and the other one called slib-slib:

------File Analysis------

Sorting files into the required packages.
Creating the directory structure.
Copying files to be packaged…OK
Adding scripts and repository data.

The following packages have been detected:
“phscrs” is the CPU-independent package.
“phscrs-host_x86” is the x86-specific package.
“phscrs-dev” is the CPU-independent package of “dev”.
“phscrs-dev-target_x86” is the CPU-independent package of
“dev” for developing x86 code.
“phscrs-slib” is the CPU-independent package of “slib”.
“phscrs-slib-host_x86” is the x86-specific package of “slib”.
“phscrs-slib-slib” is the CPU-independent package of “slib-slib”.
“phscrs-slib-slib-host_x86” is the x86-specific package holding
just the shared library files of “slib”.

Ok, what’s the need of generating a package holding just the shared
libraries when slib ALREADY contains the same library.
slib and slib-slib are identical.
Packager here seems to recognize slib as a new package, not the
“slib” package (unless I’m doing something wrong and slib package
is referred to something else).

Bests


Wave++


Wave++

Okay, here’s a two part answer to your problem.

Part 1: You need a better understanding of what ‘slib’ packages
are. Please read the section called “SLIB packages” in part 2 of
my packaging article on QDN:
http://qdn.qnx.com/articles/sep1401/index.html
Remember that packager makes a slib package automatically,
so you (almost) never need to put component=“slib” in a QPG.

Part 2: The original problem of your library not being included
properly is the thing that you have to fix. The problem is that
packager assumes that .so files are DLLs, not Shared Objects
(please don’t ask me to make the distinction, I get confustd too).
To force packager to think that your .so file is a Shared Object,
you can add a filetype=“so” on the QPG:Add line that original-
ly puts your .so into your package. Or, if you’re adding a tree of
files, just add a rule inside the Add line:

<QPG:Add type=“tree” file=“myfiles” install="/">
<QPG:Rule argument="*.so" filetype=“so”/>
</QPG:Add>

If you’re confused, just send me your QPG file, and I’ll make the
change for you!

Jerry Chappell
jchappell@qnx.com

Jerry Chappell <jchappell@qnx.com> wrote:

Okay, here’s a two part answer to your problem.

Part 1: You need a better understanding of what ‘slib’ packages
are. Please read the section called “SLIB packages” in part 2 of
my packaging article on QDN:
http://qdn.qnx.com/articles/sep1401/index.html
Remember that packager makes a slib package automatically,
so you (almost) never need to put component=“slib” in a QPG.

I’ve read that arrticle at least 5 times but never caught the slib
part. Sorry :slight_smile:.
Another question (since we’re discussing again on it), .so files
(shared objects for clarity) must be present in both the “application”
package and in the slib one?

Part 2: The original problem of your library not being included
properly is the thing that you have to fix. The problem is that
packager assumes that .so files are DLLs, not Shared Objects
(please don’t ask me to make the distinction, I get confustd too).

Shared objects usually are linked dinamically into some applications,
dlls are shared objects too, but they’re use primarly for dynloading
functions, like for plugins.

Both ends in .so but shared objects are more common and should be the
default (I think).

To force packager to think that your .so file is a Shared Object,
you can add a filetype=“so” on the QPG:Add line that original-
ly puts your .so into your package. Or, if you’re adding a tree of
files, just add a rule inside the Add line:

<QPG:Add type=“tree” file=“myfiles” install="/"
<QPG:Rule argument="*.so" filetype=“so”/
</QPG:Add

If you’re confused, just send me your QPG file, and I’ll make the
change for you!

I’m sure they’re shared objects, not dlls, so I’ll try to add these
lines.

Thanks again for your infinite patience :slight_smile:

Jerry Chappell
jchappell@qnx.com


Wave++

Wave++ <wavexx@trinity.codewiz.org> wrote:

I’ve read that arrticle at least 5 times but never caught the slib
part. Sorry > :slight_smile:> .
Another question (since we’re discussing again on it), .so files
(shared objects for clarity) must be present in both the “application”
package and in the slib one?

When packager detects a shared object being packaged, it
automatically places a copy of it into a corresponding slib package.
This package SHOULD NOT BE INSTALLED, as part of a normal
installation. It is only there for DEPENDENCY RESOLUTION. If some
other package requires your shared objects, then only your
SLIB package(s) will be installed in order to satisfy their dependency;
your full (and potentially huge) package needs not be installed.

Shared objects usually are linked dinamically into some applications,
dlls are shared objects too, but they’re use primarly for dynloading
functions, like for plugins.
Both ends in .so but shared objects are more common and should be the
default (I think).

Thanks for the clarification. If packager sees myfile.so.1 (or any number),
it knows it’s a shared object, not a DLL. In-house, we always put the
version number on the end of the shared object filenames, so that
works fine. If you don’t have a number on the end of the filename, that’s
where you have to explicitly tell packager that your .so is actually a
shared object.

I’m sure they’re shared objects, not dlls, so I’ll try to add these
lines.

Thanks again for your infinite patience > :slight_smile:

Not a problem.

Jerry

Jerry Chappell <jchappell@qnx.com> wrote:

When packager detects a shared object being packaged, it
automatically places a copy of it into a corresponding slib package.
This package SHOULD NOT BE INSTALLED, as part of a normal
installation. It is only there for DEPENDENCY RESOLUTION. If some
other package requires your shared objects, then only your
SLIB package(s) will be installed in order to satisfy their dependency;
your full (and potentially huge) package needs not be installed.

Ok, this time I should get it :slight_smile:
Packager now does things as expected.

Thanks for the clarification. If packager sees myfile.so.1 (or any number),
it knows it’s a shared object, not a DLL. In-house, we always put the
version number on the end of the shared object filenames, so that
works fine. If you don’t have a number on the end of the filename, that’s
where you have to explicitly tell packager that your .so is actually a
shared object.

I’m using the neutrino makefile convention but found no way to specify
the library version other than SO_VERSION in common.mk:

SO_VERSION=1

This will include version informations in the so but the name will
remain .so without any version specification.
Do you know some way to build directly a file ending in .so.VERSION?

I’m sure they’re shared objects, not dlls, so I’ll try to add these
lines.

Thanks again for your infinite patience > :slight_smile:

Not a problem.

Jerry

wavexx@trinity.codewiz.org wrote:

Ok, this time I should get it > :slight_smile:
Packager now does things as expected.

I’m using the neutrino makefile convention but found no way to specify
the library version other than SO_VERSION in common.mk:
SO_VERSION=1
This will include version informations in the so but the name will
remain .so without any version specification.
Do you know some way to build directly a file ending in .so.VERSION?

All you have to do at that point is execute a ‘make install’ to have the
make utility change the version number as you need it.

However, there is another (more elegant) solution…

In your common.mk file, following the line which reads:
include $(QCONFIG)

Add the following section:
define PINFO
PINFO NAME=MyApp
PINFO DESCRIPTION=Performs actions that are required by the user
endef

This tells make to generate a filename.pinfo file (your app/lib
name with .pinfo appended to it). The pinfo file includes information
like the installation directory, symbolic links, build date, etc.

The good news is that Packager can use this .pinfo file in its
QPG file instead of you having to enter the information yourself:
<QPG:Add file=“nto/x86/*/myapp” pinfo=“myapp.pinfo”/>

In this way, you don’t have to copy your files into the directory
structure either. Just leave it where it has been built, and packager
will find the file and package it into the location to which it should
be installed. It also puts in a symlink so that your shared object
has a link to the latest version, too!

Jerry

Wave++ wrote:

Shared objects usually are linked dinamically into some applications,
dlls are shared objects too, but they’re use primarly for dynloading
functions, like for plugins.

Both ends in .so but shared objects are more common and should be the
default (I think).

Uh, I’m just lurking here, but I still don’t get it. Could you
give some examples that would make this distinction more clear?
What is the difference between “linked dynamically” and “dynloading
functions”? I see they are both shared objects, both linked or
loaded dynamically into some applications…

Norton Allen <allen@huarp.harvard.edu> wrote:

Uh, I’m just lurking here, but I still don’t get it. Could you
give some examples that would make this distinction more clear?
What is the difference between “linked dynamically” and “dynloading
functions”? I see they are both shared objects, both linked or
loaded dynamically into some applications…

Well, they’re both shared libraries. They’re created in the same way.
This is an usage distinction.

Let’s make an example: if you make a library some program may
decide to link at it. In this way the executable is linked dynamically
to the library: ld loads automatically the needed functions into
memory when needed. That’s it. If the library is missing, the
executable won’t run at all.

Instead, if you plan to build a dll (dynamic loading library) the
executable isn’t linked with it. You need to fetch manually a function
from the shared object by using a symbol with dlsym().
You need to open a shared library with an open like call, fetch a
pointer to a function with dlsym and then use this pointer as a
function.
If the library is missing the executable will run s usual (will fail
to open the library of course).

That’s the way of implementing such things like plugins.
The executable doesn’t know the library at compile time. Instead
will load manually selected functions from any shared object that
contains some predefined symbols.

As both are shared object, both can be used for dynamic loading.
dlls usually don’t contains version information and don’t provide an
header that is necessary for using it when linking at compile time.

Hope this can clarify.

Wave++

Wave++ wrote:

Hope this can clarify.

Absolutely. Thank you. -Norton

Jerry Chappell <jchappell@qnx.com> wrote:

wavexx@trinity.codewiz.org > wrote:
Ok, this time I should get it > :slight_smile:
In your common.mk file, following the line which reads:
include $(QCONFIG)

Add the following section:
define PINFO
PINFO NAME=MyApp
PINFO DESCRIPTION=Performs actions that are required by the user
endef

I’ve done this in a test package and the resulting .pinfo file contains
2 istances of NAME (the first one by $(PRODUCT) I think, and the second
one by PINFO)

common.mk:


define PINFO
PINFO NAME=TestApp
PINFO DESCRIPTION=Blah
endef

resulting testapp.pinfo:

STATE=Experimental
INSTALLDIR=x86//usr/bin/
INSTALLNAME=testapp
NAME=testapp
USER=wavexx
HOST=genesy
DATE=2001/10/16-03:49:07cet
NAME=TestApp
DESCRIPTION=Blah

Is the double histance of NAME normal?

This tells make to generate a filename.pinfo file (your app/lib
name with .pinfo appended to it). The pinfo file includes information
like the installation directory, symbolic links, build date, etc.

The good news is that Packager can use this .pinfo file in its
QPG file instead of you having to enter the information yourself:
<QPG:Add file=“nto/x86/*/myapp” pinfo=“myapp.pinfo”/

In this way, you don’t have to copy your files into the directory
structure either. Just leave it where it has been built, and packager
will find the file and package it into the location to which it should
be installed. It also puts in a symlink so that your shared object
has a link to the latest version, too!

Jerry


Wave++

Wave++ <wavexx@apexmail.com> wrote:

I’ve done this in a test package and the resulting .pinfo file contains
2 istances of NAME (the first one by $(PRODUCT) I think, and the second
one by PINFO)

The last one found in the pinfo will be used, but you’re right, that
usually should not happen. So don’t bother putting the NAME=
into the common.mk, since make does it for you automatically.

Jerry

Jerry Chappell a écrit :

wavexx@trinity.codewiz.org > wrote:
Ok, this time I should get it > :slight_smile:
Packager now does things as expected.

I’m using the neutrino makefile convention but found no way to specify
the library version other than SO_VERSION in common.mk:
SO_VERSION=1
This will include version informations in the so but the name will
remain .so without any version specification.
Do you know some way to build directly a file ending in .so.VERSION?

All you have to do at that point is execute a ‘make install’ to have the
make utility change the version number as you need it.

However, there is another (more elegant) solution…

In your common.mk file, following the line which reads:
include $(QCONFIG)

Add the following section:
define PINFO
PINFO NAME=MyApp
PINFO DESCRIPTION=Performs actions that are required by the user
endef

This tells make to generate a filename.pinfo file (your app/lib
name with .pinfo appended to it). The pinfo file includes information
like the installation directory, symbolic links, build date, etc.

The good news is that Packager can use this .pinfo file in its
QPG file instead of you having to enter the information yourself:
QPG:Add file=“nto/x86/*/myapp” pinfo=“myapp.pinfo”/

In this way, you don’t have to copy your files into the directory
structure either. Just leave it where it has been built, and packager
will find the file and package it into the location to which it should
be installed. It also puts in a symlink so that your shared object
has a link to the latest version, too!

Jerry

So, in my QPG file, the following lines:
<QPG:Add file=“pilot_motor_API/public/libpilot_motor_API.h”
install="/usr/include/"/>
<QPG:Add file=“pilot_motor/nto/x86/o/pilot_motor”
install="/usr/bin/"/>
<QPG:Add file=“pilot_motor_API/nto/x86/so/libpilot_motor_API.so”
install="/usr/lib/libpilot_motor_API.so.1"/>
<QPG:Add file=“pilot_motor_API/nto/x86/a/libpilot_motor_API.a”
install="/x86/usr/lib/"/>
<QPG:Add file=“pilot_motor_API/nto/x86/so/libpilot_motor_APIS.a”
install="/x86/usr/lib/"/>
<QPG:Add file=“pilot_motor_API/nto/x86/so/libpilot_motor_API.so”
install="/usr/lib/libpilot_motor_API.so.1" component=“slib”/>
<QPG:Add file=“libpilot_motor_API.so” install="/x86/usr/lib/"
filetype=“symlink” linkto=“libpilot_motor_API.so.1”/>



should be replaced by:

No pinfo for the following ‘Add file’! Normal?

<QPG:Add file=“pilot_motor_API/public/libpilot_motor_API”
install="/usr/include/"/>

<QPG:Add file=“pilot_motor/nto/x86/o/pilot_motor”
pinfo=“pilot.pinfo”/>
<QPG:Add file=“pilot_motor_API/nto/x86/so/libpilot_motor_API.so”
pinfo=“libpilot_motor_API.so.pinfo”/>
<QPG:Add file=“pilot_motor_API/nto/x86/a/libpilot_motor_API.a”
pinfo=“libpilot_motor_API.a.pinfo”/>
<QPG:Add file=“pilot_motor_API/nto/x86/so/libpilot_motor_APIS.a”
pinfo=“libpilot_motor_APIS.a.pinfo”/>

What about the slib line?

<QPG:Add file=“pilot_motor_API/nto/x86/so/libpilot_motor_API.so”
install="/usr/lib/libpilot_motor_API.so.1" component=“slib”/>

And I can remove the following line: correct ?

<QPG:Add file=“libpilot_motor_API.so” install="/x86/usr/lib/"
filetype=“symlink” linkto=“libpilot_motor_API.so.1”/>


Regards,
Alain.

Jerry Chappell a écrit :

wavexx@trinity.codewiz.org > wrote:
Ok, this time I should get it > :slight_smile:
Packager now does things as expected.

I’m using the neutrino makefile convention but found no way to specify
the library version other than SO_VERSION in common.mk:
SO_VERSION=1
This will include version informations in the so but the name will
remain .so without any version specification.
Do you know some way to build directly a file ending in .so.VERSION?

All you have to do at that point is execute a ‘make install’ to have the
make utility change the version number as you need it.

However, there is another (more elegant) solution…

In your common.mk file, following the line which reads:
include $(QCONFIG)

Add the following section:
define PINFO
PINFO NAME=MyApp
PINFO DESCRIPTION=Performs actions that are required by the user
endef

This tells make to generate a filename.pinfo file (your app/lib
name with .pinfo appended to it). The pinfo file includes information
like the installation directory, symbolic links, build date, etc.

The good news is that Packager can use this .pinfo file in its
QPG file instead of you having to enter the information yourself:
QPG:Add file=“nto/x86/*/myapp” pinfo=“myapp.pinfo”/

In this way, you don’t have to copy your files into the directory
structure either. Just leave it where it has been built, and packager
will find the file and package it into the location to which it should
be installed. It also puts in a symlink so that your shared object
has a link to the latest version, too!

Jerry

Maybe a problem when you generate the pinfo file:
If we decide that the INSTALLDIR=/dev/null, usefull in the o.g, so.g, etc…
directories, it becomes INSTALLDIR=/x86//dev/null in the pinfo file which
seems not correct.

Regards,
Alain.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

No pinfo for the following ‘Add file’! Normal?

QPG:Add file=“pilot_motor_API/public/libpilot_motor_API”
install="/usr/include/"/

I’m not sure why there’s no pinfo for it. Check your common.mk.

QPG:Add file=“pilot_motor/nto/x86/o/pilot_motor”
pinfo=“pilot.pinfo”/
QPG:Add file=“pilot_motor_API/nto/x86/so/libpilot_motor_API.so”
pinfo=“libpilot_motor_API.so.pinfo”/
QPG:Add file=“pilot_motor_API/nto/x86/a/libpilot_motor_API.a”
pinfo=“libpilot_motor_API.a.pinfo”/

These are correct, but you can simplify it further by using the ‘$’
qualifier which just appends .pinfo to your filename…

<QPG:Add file=“pilot_motor/nto/x86/o/pilot_motor” pinfo=“pilot.pinfo”/>
<QPG:Add file=“pilot_motor_API/nto/x86/so/libpilot_motor_API.so” pinfo="$"/>
<QPG:Add file=“pilot_motor_API/nto/x86/a/libpilot_motor_API.a” pinfo="$"/>
<QPG:Add file=“pilot_motor_API/nto/x86/so/libpilot_motor_APIS.a” pinfo="$"/>

What about the slib line?

Packager puts the slibs in itself, you should therefore remove any
line which has component=“slib”.

And I can remove the following line: correct ?

QPG:Add file=“libpilot_motor_API.so” install="/x86/usr/lib/"
filetype=“symlink” linkto=“libpilot_motor_API.so.1”/

Yes, that will be part of one of your pinfo files, so you don’t need
to explicitly have it in there.

Jerry Chappell

Jerry Chappell a écrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:

No pinfo for the following ‘Add file’! Normal?

QPG:Add file=“pilot_motor_API/public/libpilot_motor_API”
install="/usr/include/"/

I’m not sure why there’s no pinfo for it. Check your common.mk.

?!? Don’t know what I’m supposed to do in my common.mk, I just add the pinfo
block.
The problem with the public directory is that nothing is done in it during build
time. It’s just took into account at install time so, I think it’s because no
…pinfo file is generated. Agree?

Regards,
Alain.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

?!? Don’t know what I’m supposed to do in my common.mk, I just add the pinfo
block.
The problem with the public directory is that nothing is done in it during build
time. It’s just took into account at install time so, I think it’s because no
.pinfo file is generated. Agree?

Agreed.