PerlAlien / Alien-Build

Build external dependencies for use in CPAN
16 stars 25 forks source link

Alien Author docs related to "make install" and DESTDIR #396

Open nrdvana opened 1 year ago

nrdvana commented 1 year ago

I wrote an alien module for FluentBit, and its make process generates a broken fluent-bit.h. While I'm waiting to get this fixed upstream, I needed to just inject my own header into the staging directory after the "make install" runs. I had a difficult time with the documentation to figure out how to do this.

The first point of confusion (reading the Author Manual) was the example of

'./configure --prefix=%{.install.prefix} --disable-shared'

which would indicate that the build process is actually installing to ->install_prop->{prefix}, but this is not the case. (I was using cmake, but just assumed it would follow the same pattern as automake)

The second confusion was the example where it shows

prefix: /tmp/7RtAusykNN

which would also indicate ->install_prop->{prefix} was pointing to the staging directory at some stage of the build. My testing (again, with the cmake plugin) seems to indicate that the {prefix} variables always point to the final installation path, which doesn't exist at the time the module is first installed.

The ->{stage} variable isn't mentioned in the entire Author Documentation, but when I found that I assumed it was what I was looking for, but it seems it doesn't get populated until some time after the 'Gather' stage.

I finally dug into the source for ::Plugin::Gather::IsolateDynamic and found

      my $install_root;
      if($build->meta_prop->{destdir})
      {
        my $destdir = $ENV{DESTDIR};
        $install_root = Path::Tiny->new(_destdir_prefix($ENV{DESTDIR}, $build->install_prop->{prefix}));
      }
      else
      {
        $install_root = Path::Tiny->new($build->install_prop->{stage});
      }

which seems to be what I needed.

My resulting solution to my problem is Alien::FluentBit alienfile

Proposed Changes

For the Author, I think it would be helpful to structure the documentation per each each phase of the alienfile, describing the initial state of things, what the directives are supposed to accomplish, and the resulting state that should be achieved.

I get the idea that DESTDIR is an implementation detail that complicated the original clean plan for staging the builds? If so, there should at least be some wrapper around that so that alien authors can find the location of the directory that 'make install' just wrote to so that they can perform final adjustments to those files during the 'build' phase. Ideally it would be the same code for automake and cmake, regardless of where they are actually writing their directories. It could be something as simple as running the above code and storing it in ->install_prop->{make_install_dir}.

nrdvana commented 1 year ago

I'm proposing a fairly large restructuring here, but this is what I envision would be the most helpful document to consult when I'm trying to remember how to write an alien module:


DESCRIPTION

Overview

... an alienfile ...

... a Installer ...

... a package ...

Example dir list

Note about wanting static libs

Other general points about plugins etc.

The alienfile

Here's an example alienfile

Probe Phase

... the probe phase returns 'system' or 'share' ...

... don't perform work in this block because it can be skipped with env variables ...

The shorthand notation probe [...] means ...

The longhand probe sub { ... } should take these steps and do these things.

...You can find this information in these install variables....

The Share Block

... you need to fetch the code ... extract the code to (directory) ...

... build it using automake etc ...

... gather the details to be made available at runtime ...

There might be extra deps that building needs that sys doesn't. You can add 'requires' directives etc.

Share - Fetch

... use these common tools to get your code ... (start_url, download, extract)

Mention various common plugins.

warnings/advice about choosing versions

At the end, the files need to be extracted at this location etc. so the build plugins can find them.

Apply patches to the files like this.

Share - Build

You start with this var pointing to the extracted sources, you need to populate that directory, etc.

... common patterns of automake or cmake ...

reference all the notations usable in 'build' rules. Maybe link to external docs.

How to expose 'configure' options to the end user? Recommendations, tools?

If you need to modify the files before they get installed, do like this.

Gather

This phase can either be inside the 'Share' or 'sys' sections or at root scope of the alienfile if it applies to both modes.

Common patterns. pkg-info. make sure these vars are set. relation between libs, libs_static, libs_dynamic, etc.

current section "nonstandard configuration"

Common Plugins

give a brief summary of all the useful plugins and which steps they replace. Link to plugin for futher details.

af debugger

Installer Integration

MakeMaker

Big example

Module::Build

Link

Dist::Zilla

Small example

Module

Mention extra methods for exporting custom things

Unit Tests

plicease commented 1 year ago

I do really like this structure, when I get time I will try and rewrite some of the documentation appropriately.