Search code examples
c++linuxtarautotools

How to change the format of tarballs when running `make dist` in autotools


I'm using GNU Autotools to build my C++ project. And I want to use make dist to create a tarball of my project.

However, the default format of tar is gnu, which supports only paths with no more than 99 characters.

But in my project, some paths of files exceed this limitation, so I want to change the format to pax or others. What can I do?


I have tried to specify the TAR variable as TAR='tar --format=pax' make dist but it failed.

After some investigations, I found that the command executed is:

$${{TAR-tar}} chof - target | eval GZIP= gzip --best -c > data.tar.gz

(where target is the target directory), where the value of $${{TAR-tar}} is the variable TAR I specified.

So when I specify that TAR='tar --format=pax', the command becomes:

tar --format=pax chof - target | eval GZIP= gzip --best -c > data.tar.gz

which is wrong, and gives me error messages as below:

tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options

And the correct command should be:

tar chof - target --format=pax | eval GZIP= gzip --best -c > data.tar.gz

(--format=pax should be placed after -).

Then how can I change the format of tar?


Inspired by the comments below, I suddenly found that in the command tar chof - target, there is an option o in chof. This option means --old-archive acccording to the manual in tar --help, which means the tar will use the v7 format. Then the question seems to be how to remove the o option specified by autotools, i.e. change the command to tar chf - target.


Solution

  • @CraigEstey, I was supposing that the OP might have encountered an actual issue with stored filename lengths. Anyway, I think the question could be saved by changing the assertion about GNU tar to a general concern about less-capable tars. In that case, the approach you suggested in your first comment would make a suitable answer.

    Under linux, the default tar is gnu tar. Its default format is either gnu or posix (depending on version). So, it should not have any filename length restrictions. See: https://www.gnu.org/software/tar/manual/tar.html#Formats


    However, if the default tar is not gnu tar, one way is:

    1. create a script (e.g.) mytar, have it rearrange the args as desired and then do exec tar with the new args.
    2. Then, use TAR=mytar.

    Your script could even mangle the args further and invoke whatever you want (e.g.):

    1. exec pax <some_args>
    2. exec /full/path/to/gnu/tar <some_args>
    3. exec zip <some_args>

    Other possibilities are that your filename components have spaces or some non-ascii chars that are problematic.

    It's perfectly fine to place source in whatever "longish" paths you want on your development system. However, usually, a distribution package would be be better received without "excessively" long pathnames. That is, maybe install as /usr/local/myproject/{bin,lib}/...


    UPDATE:

    Inspired by the comments below, I suddenly found that in the command tar chof - target, there is an option o in chof. This option means --old-archive acccording to the manual in tar --help, which means the tar will use the v7 format. Then the question seems to be how to remove the o option specified by autotools, i.e. change the command to tar chf - target

    As mentioned above, using a script will help. Here's a perl script [Side note: I hate *sh :-)]:

    #!/usr/bin/perl
    # mytar -- force autotools to _not_ use "o"
    
    foreach my $arg (@ARGV) {
        $arg =~ s/chof/chf/;
    }
    
    exec("tar",@ARGV);