[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: default directories in installed library projects



Nicolas Boulenguez wrote:
> This message answers
> https://lists.debian.org/debian-ada/2013/09/msg00005.html
> 
> > users have to use setarch instead of passing an option such as -m32
> 
> Gnat will not be able to cross-compile before long.

Are you saying that all multiarch and cross-compilation functionality
will be removed from Gnat? In Debian or in the upstream GCC sources?
How will Gnat be bootstrapped on new architectures then?

> Why not hardcode
> the hardware platform into directories.gpr? Could you give an example
> where gnat needs to receive a target architecture at compile time?

If each binary Gnat package can only be used to compile for a single
architecture, there can never be more than one Gnat present at a time,
and each Gnat package comes with its own version of the directories
project, then a constant Hardware_Platform should work. You'll need to
prevent a situation where a 32-bit Gnat and a 64-bit GPRbuild are
installed, and GPRbuild doesn't find the directories project because
Gnat installs it in a 32-bit directory but GPRbuild looks for it in a
64-bit directory.

If that is the case, then it seems rather pointless to install -dev
packages for other architectures than the compiler's target
architecture, so it shouldn't matter much if they aren't multiarch-
compatible.

If there is any way that a user can choose to build for different
architectures without installing and uninstalling packages in between,
then the directories project needs to be adapted at run time somehow.
Instead of parameterizing a single directories project you could perhaps
do it by manipulating GPR_PROJECT_PATH to make the builders find the
right directories project, if you think that works better for Debian.

In Fedora I think manipulating the project search path would be more
trouble than our current solution, but the situation in Debian might be
different. What matters is that our directories projects present the
same interface to other project files. The mechanism used to make the
directories project multiarch-capable doesn't have to be the same.

> > how do you feel about "operating_system_directories", or
> > "os_directories" for short? Or is "distribution_directories" better?
> 
> I prefer "distribution_directories" or even
> "distribution_directory_layout".

That would also work.

> > I fail to imagine why anyone would write architecture-dependent
> > package specifications in Ada. It shouldn't be hard to encapsulate
> > the architecture-dependent bits in a package body.
> 
> Architecture-dependent package specifications seem a necessary pain
> for C bindings like gmp, ncurses, gtk, qt.

Fedora's GtkAda-devel package stores both package specifications and
bodies in /usr/include/gtkada. The 32- and 64-bit versions of the
package can both be installed at the same time. There is no conflict
because all of the source files are identical in both packages. They
just share ownership of the files. If any of the files were different,
then RPM would see a conflict and refuse to install both packages.

I don't know about the other three but for a binding to GTK+ there is
apparently no need for anything architecture-dependent.

That said, I have already accepted Archincludedir. I just think anyone
who plans to use it should think twice about it, and try to restructure
their code instead.

> For Bindir and Libexecdir: could you please provide an example
> scenario of use of these variables? If an user ever installs his
> library system-wide, he will probably want to avoid locations used by
> the distributions, and select something like /usr/local or /opt
> instead. Our project only intends to help him during compilation.

Let's say a source package contains both a library and a program to be
run by programs. It could have project files like these to control the
build:

with "distribution_directory_layout.gpr";
library project Build_Library is
   package DDL renames Distribution_Directory_Layout;
   for Library_Name      use "library";
   for Library_Kind      use "dynamic";
   for Library_Version   use "liblibrary.so.1";
   for Library_Interface use ("Library");
   for Source_Dirs       use ("src/library");
   for Object_Dir        use "obj/library";
   for Library_Src_Dir   use "stage" & DDL.Includedir & "/library";
   for Library_Dir       use "stage" & DDL.Libdir;
   for Library_ALI_Dir   use "stage" & DDL.Alidir & "/library";
end Build_Library;

with "distribution_directory_layout.gpr";
standard project Build_Program is
   package DDL renames Distribution_Directory_Layout;
   for Main        use ("program");
   for Source_Dirs use ("src/program");
   for Object_Dir  use "obj/program";
   for Exec_Dir    use "stage" & DDL.Libexecdir;
end Build_Program;

Thus a directory tree that corresponds exactly to the files' final
locations is constructed in a staging directory named "stage". The files
of the library are written in Includedir, Libdir and Alidir under the
staging directory, and the program is written in Libexecdir under the
staging directory. Installation then amounts to recursively copying the
whole directory tree under stage to the root directory. This will put
all the files where you want them when you package this software in
Debian.

A user who builds the software locally could use another directories
project where the variables' values begin with "/usr/local". During the
build the files will then be put in directories under stage/usr/local,
and when the contents of stage are copied to / the files end up under
/usr/local.

> > This example shows a shared library that depends on a second
> > library but isn't linked to that library. Instead the first library
> > requires that programs and libraries that use it must link to the
> > second library. I suppose this is normal for static libraries, but
> > a shared library should normally be linked to the libraries it
> > depends on.
> 
> On Debian at least, if libbar depends on libfoo, -lfoo must be given
> both when linking libbar and later when linking an executable with
> libbar.  I have read what you say in some documentations, but the link
> step actually failed every time I tried.

I have C++ programs that use MySQL++. I link them with -lmysqlpp.
libmysqlpp.so.3 is linked to libmysqlclient.so.18, which in turn is
linked to libz.so.1, libdl.so.2 and librt.so.1. I do not pass 
-lmysqlclient, -lz, -ldl or -lrt to the linker. It works fine on Debian.

My own Ada Milter API is a binding to Libmilter. Importing
milter_api.gpr causes -ladamilter to be passed to the linker. -lmilter
is not needed. libmilter.so.1.0.1 is pulled in automatically by
libadamilter-2.1.1.so.0. On Debian.

If you run "readelf --dynamic /path/to/libbar.so" you should see a line
like this, if libbar has been linked to libfoo correctly:
 0x00000001 (NEEDED)                     Shared library: [libfoo.so.1]

Of course, if the program itself uses libfoo directly, then it should
be linked using -lfoo (but you can get away with omitting it if
--copy-dt-needed-entries is on).

> Libexecdir: you write
>    The top-level directory for programs that are intended to be run by
>    other programs rather than by users.
> I prefer:
>    The parent of libraries' separate library-specific directories for
>    programs that...
> because the Debian policy recommends it (A subdirectory named after
> the package ensures that the path depends on the SOversion).

Let's see what other specifications and policies say. The oldest
specification of libexecdir that I know of is the GNU Coding Standards:

| "The definition of ‘libexecdir’ is the same for all packages, so you
| should install your data in a subdirectory thereof."
https://www.gnu.org/prep/standards/html_node/Directory-Variables.html

Seeing as "should" is used throughout the specification and "must"
occurs only rarely, this reads like a very strong recommendation to
use a subdirectory. The wording is exactly the same as for datadir
(/usr/share).

The current version of the Filesystem Hierarchy Standard doesn't
mention /usr/libexec, but has this to say about /usr/lib:

| /usr/lib includes object files, libraries, and internal binaries that
| are not intended to be executed directly by users or shell scripts.
| 
| Applications may use a single subdirectory under /usr/lib. If an
| application uses a subdirectory, all architecture-dependent data
| exclusively used by the application must be placed within that
| subdirectory.
http://www.pathname.com/fhs/pub/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA

In a more or less active effort to release an updated FHS, a section
on /usr/libexec has been added:

| /usr/libexec includes internal binaries that are not intended to be
| executed directly by users or shell scripts. Applications may use a
| single subdirectory under /usr/libexec.
http://www.linuxbase.org/betaspecs/fhs/fhs.html#usrlibexec

In both cases the FHS leaves it to programmers to choose whether they
want to use a subdirectory or not. For /usr/share, on the other hand, it
actually gives a recommendation:

| It is recommended that a subdirectory be used in /usr/share [...]

The Fedora Packaging Guidelines say:

| Packagers are highly encouraged to store libexecdir files in a
| package-specific subdirectory of %{_libexecdir}, such as
| %{_libexecdir}/%{name}.
https://fedoraproject.org/wiki/Packaging:Guidelines#Libexecdir

"Highly encouraged" but not required. Several packages don't follow this
recommendation. I find lots of programs directly in /usr/libexec on my
Fedora boxes. This is quite different from /usr/share, where I find
nothing but subdirectories except for a single symlink.

I haven't found the Debian policy on this, but you say that it
recommends subdirectories, not that it requires them. I find a few
programs directly in /usr/lib on my Debian boxes (including gprbind and
gprlib).

There are vastly more programs that aren't in subdirectories in Fedora
than in Debian, but that may well be because my Fedora boxes have lots
of GUI software installed while the Debian ones are headless servers
with much smaller selections of packages.

Obviously opinions differ on this. Originally I didn't intend to write
a policy, only define what the variables mean, but I realize that the
more we can convince developers to use subdirectories, the less trouble
packagers will have with changing pathnames to avoid conflicts or adhere
to their distributions' policies. "Library-specific" isn't correct
though. These programs don't necessarily belong to a particular library,
and although they are conceptually similar to library functions we don't
normally call them libraries. Perhaps we can call the directory
"package-specific" or "application-specific".

I think a little more verbosity is needed if the directories project
specification is going to be a policy document. I'll try to write
something.

Björn

Attachment: signature.asc
Description: PGP signature


Reply to: