Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExtUtils::CBuilder uses ld to link programs, thus failing #13531

Open
p5pRT opened this issue Jan 16, 2014 · 13 comments
Open

ExtUtils::CBuilder uses ld to link programs, thus failing #13531

p5pRT opened this issue Jan 16, 2014 · 13 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 16, 2014

Migrated from rt.perl.org#121017 (status was 'open')

Searchable as RT121017$

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2014

From schmorp@schmorp.de

Created by schmorp@schmorp.de

Subject basically says it all, ExtUtils​::CBuilder errornously tries to use
$Config{ld} to link programs, thus failing on many platforms. Correct
would be $Config{cc}.

The symptom is a lot of modules fialing entirely or installing pure-perl
versions because ExtUtils​::CBuilder tries to link a test program as shared
library without specifying the corretc flags (as obviously it tries to
build a standalone program).

This most often, but not always, happens when modules use the
->have_compiler in their Makefile.PL which errornously returns false.

Whats more, on systems that do not use dynamic loading, $Config{ld} always
seems to default to "ld", which might be binary incompatible (and might be
another bug - the documentation says on ELF systems (why only there?) it
should be the same as $cc, but Configure always sets it to "ld", even with
-Dld=xx specified).

The only workaround is to define LD in the environment, which is the wrong
symbol and can break legitimate uses.

Perl Info

Flags:
    category=library
    severity=low
    module=ExtUtils::CBuilder

Site configuration information for perl 5.18.1:

Configured by Marc Lehmann at Mon Oct 21 09:27:08 CEST 2013.

Summary of my perl5 (revision 5 version 18 subversion 1) configuration:
   
  Platform:
    osname=linux, osvers=3.10-3-amd64, archname=x86_64-linux
    uname='linux cerebro 3.10-3-amd64 #1 smp debian 3.10.11-1 (2013-09-10) x86_64 gnulinux '
    config_args='-Duselargefiles -Duse64bitint -Dusemymalloc=n -Dstatic_ext=Fcntl -Dcc=ccache gcc -Dccflags=-DPERL_DISABLE_PMC -DPERL_ARENA_SIZE=16376 -USITEARCH_EXP -USITELIB_EXP -UARCHLIB_EXP -D_GNU_SOURCE  -I/opt/include -ggdb -gdwarf-2 -g3 -Doptimize=-O6 -fno-asynchronous-unwind-tables -fno-strict-aliasing -Dcccdlflags=-fPIC -Dldflags=-L/opt/perl/lib -L/opt/lib -Dlibs=-ldl -lm -lcrypt -Dprefix=/opt/perl -Dprivlib=/opt/perl/lib/perl5 -Darchlib=/opt/perl/lib/perl5 -Uusevendorprefix -Dsiteprefix=/opt/perl -Dsitelib=/opt/perl/lib/perl5 -Dsitearch=/opt/perl/lib/perl5 -Dsitebin=/opt/perl/bin -Dman1dir=/opt/perl/man/man1 -Dman3dir=/opt/perl/man/man3 -Dsiteman1dir=/opt/perl/man/man1 -Dsiteman3dir=/opt/perl/man/man3 -Dman1ext=1 -Dman3ext=3 -Dpager=/usr/bin/less -Uafs -Uusesfio -Uusenm -Uuseshrplib -Ud_dosuid -Dusethreads=undef -Duse5005threads=undef -Duseithreads=undef -Dusemultiplicity=undef -Demail=perl-binary@plan9.de -Dcf_email=perl-binary@plan9.de -Dcf_by=Marc Lehmann -Dlocincpth=/opt/perl/include /opt/include -Dmyhostname=localhost -Dmultiarch=undef -Dbin=/opt/perl/bin -Dxxxusedevel -DxxxDEBUGGING -Dxxxuse_debugging_perl -Dxxxuse_debugmalloc -dEs'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='ccache gcc', ccflags ='-DPERL_DISABLE_PMC -DPERL_ARENA_SIZE=16376 -USITEARCH_EXP -USITELIB_EXP -UARCHLIB_EXP -D_GNU_SOURCE -I/opt/include -ggdb -gdwarf-2 -g3 -fno-strict-aliasing -pipe -I/opt/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O6 -fno-asynchronous-unwind-tables -fno-strict-aliasing',
    cppflags='-DPERL_DISABLE_PMC -DPERL_ARENA_SIZE=16376 -USITEARCH_EXP -USITELIB_EXP -UARCHLIB_EXP -D_GNU_SOURCE -I/opt/include -ggdb -gdwarf-2 -g3 -fno-strict-aliasing -pipe -I/opt/include'
    ccversion='', gccversion='4.7.2', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='ccache gcc', ldflags ='-L/opt/perl/lib -L/opt/lib -L/usr/local/lib'
    libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib
    libs=-ldl -lm -lcrypt
    perllibs=-ldl -lm -lcrypt
    libc=, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.17'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O6 -fno-asynchronous-unwind-tables -fno-strict-aliasing -L/opt/perl/lib -L/opt/lib -L/usr/local/lib'

Locally applied patches:
    


@INC for perl 5.18.1:
    /root/src/sex
    /root/pserv/lib/perl5
    /opt/perl/lib/perl5
    /opt/perl/lib/perl5
    .


Environment for perl 5.18.1:
    HOME=/root
    LANG (unset)
    LANGUAGE (unset)
    LC_CTYPE=en_US.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/root/s2:/root/s:/opt/bin:/opt/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11/bin:/usr/games:/usr/local/bin:/usr/local/sbin:/root/pserv:.
    PERL5LIB=/root/src/sex:/root/pserv/lib/perl5
    PERL5_CPANPLUS_CONFIG=/root/.cpanplus/config
    PERLDB_OPTS=ornaments=0
    PERL_ANYEVENT_DBI_TESTS=1
    PERL_ANYEVENT_LOOP_TESTS=1
    PERL_ANYEVENT_NET_TESTS=1
    PERL_BADLANG (unset)
    PERL_UNICODE=E
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2014

From schmorp@schmorp.de

Things seem more complicated - ExtUtils​::CBuilder actually tries to link
dynamic libraries all the time, even when static linking isn't even
supported by the configuration.

--
  The choice of a Deliantra, the free code+content MORPG
  -----==- _GNU_ http​://www.deliantra.net
  ----==-- _ generation
  ---==---(_)__ __ ____ __ Marc Lehmann
  --==---/ / _ \/ // /\ \/ / schmorp@​schmorp.de
  -=====/_/_//_/\_,_/ /_/\_\

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2014

From @Leont

On Thu, Jan 16, 2014 at 3​:29 PM, schmorp@​schmorp.de <
perlbug-followup@​perl.org> wrote​:

Subject basically says it all, ExtUtils​::CBuilder errornously tries to use
$Config{ld} to link programs, thus failing on many platforms. Correct
would be $Config{cc}.

On Unix, it explicitly uses $Config{cc} to link executables[1], though it
uses $Config{ld} for loadable objects. Also, $Config{cc} and $Config{ld}
tend to be identical anyway, though that depends on Configure too.

The symptom is a lot of modules fialing entirely or installing pure-perl
versions because ExtUtils​::CBuilder tries to link a test program as shared
library without specifying the corretc flags (as obviously it tries to
build a standalone program).

What flags are missing? I suspect that'd be lddlflags not being defined.

This most often, but not always, happens when modules use the

->have_compiler in their Makefile.PL which errornously returns false.

Can you give a concrete example of how you trigger this? AFAIK it usually
works.

Whats more, on systems that do not use dynamic loading, $Config{ld} always

seems to default to "ld", which might be binary incompatible (and might be
another bug - the documentation says on ELF systems (why only there?) it
should be the same as $cc, but Configure always sets it to "ld", even with
-Dld=xx specified).

ld not being overridable definitely sounds like a bug. I think on most
cases the difference doesn't matter, and in one case it's actively the more
sensible thing to do (AIX), in others it apparently doesn't.

The only workaround is to define LD in the environment, which is the wrong
symbol and can break legitimate uses.

I agree that's not much of a solution.

Leon

1​:
https://metacpan.org/source/AMBS/ExtUtils-CBuilder-0.280212/lib/ExtUtils/CBuilder/Platform/Unix.pm#L16

Platform​:
osname=linux, osvers=3.10-3-amd64, archname=x86_64-linux
uname='linux cerebro 3.10-3-amd64 #1 smp debian 3.10.11-1 (2013-09-10)
x86_64 gnulinux '
config_args='-Duselargefiles -Duse64bitint -Dusemymalloc=n
-Dstatic_ext=Fcntl -Dcc=ccache gcc -Dccflags=-DPERL_DISABLE_PMC
-DPERL_ARENA_SIZE=16376 -USITEARCH_EXP -USITELIB_EXP -UARCHLIB_EXP
-D_GNU_SOURCE -I/opt/include -ggdb -gdwarf-2 -g3 -Doptimize=-O6
-fno-asynchronous-unwind-tables -fno-strict-aliasing -Dcccdlflags=-fPIC
-Dldflags=-L/opt/perl/lib -L/opt/lib -Dlibs=-ldl -lm -lcrypt
-Dprefix=/opt/perl -Dprivlib=/opt/perl/lib/perl5
-Darchlib=/opt/perl/lib/perl5 -Uusevendorprefix -Dsiteprefix=/opt/perl
-Dsitelib=/opt/perl/lib/perl5 -Dsitearch=/opt/perl/lib/perl5
-Dsitebin=/opt/perl/bin -Dman1dir=/opt/perl/man/man1
-Dman3dir=/opt/perl/man/man3 -Dsiteman1dir=/opt/perl/man/man1
-Dsiteman3dir=/opt/perl/man/man3 -Dman1ext=1 -Dman3ext=3
-Dpager=/usr/bin/less -Uafs -Uusesfio -Uusenm -Uuseshrplib -Ud_dosuid
-Dusethreads=undef -Duse5005threads=undef -Duseithreads=undef
-Dusemultiplicity=undef -Demail=perl-binary@​plan9.de -Dcf_email=
perl-binary@​plan9.de -Dcf_by=Marc Lehmann -Dlocin
cpth=/opt/perl/include /opt/include -Dmyhostname=localhost
-Dmultiarch=undef -Dbin=/opt/perl/bin -Dxxxusedevel -DxxxDEBUGGING
-Dxxxuse_debugging_perl -Dxxxuse_debugmalloc -dEs'
hint=recommended, useposix=true, d_sigaction=define
useithreads=undef, usemultiplicity=undef
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=define, use64bitall=define, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler​:
cc='ccache gcc', ccflags ='-DPERL_DISABLE_PMC -DPERL_ARENA_SIZE=16376
-USITEARCH_EXP -USITELIB_EXP -UARCHLIB_EXP -D_GNU_SOURCE -I/opt/include
-ggdb -gdwarf-2 -g3 -fno-strict-aliasing -pipe -I/opt/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O6 -fno-asynchronous-unwind-tables -fno-strict-aliasing',
cppflags='-DPERL_DISABLE_PMC -DPERL_ARENA_SIZE=16376 -USITEARCH_EXP
-USITELIB_EXP -UARCHLIB_EXP -D_GNU_SOURCE -I/opt/include -ggdb -gdwarf-2
-g3 -fno-strict-aliasing -pipe -I/opt/include'
ccversion='', gccversion='4.7.2', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries​:
ld='ccache gcc', ldflags ='-L/opt/perl/lib -L/opt/lib -L/usr/local/lib'
libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib
/usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib
libs=-ldl -lm -lcrypt
perllibs=-ldl -lm -lcrypt
libc=, so=so, useshrplib=false, libperl=libperl.a
gnulibc_version='2.17'
Dynamic Linking​:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
cccdlflags='-fPIC', lddlflags='-shared -O6
-fno-asynchronous-unwind-tables -fno-strict-aliasing -L/opt/perl/lib
-L/opt/lib -L/usr/local/lib'

Locally applied patches​:

---
@​INC for perl 5.18.1​:
/root/src/sex
/root/pserv/lib/perl5
/opt/perl/lib/perl5
/opt/perl/lib/perl5
.

---
Environment for perl 5.18.1​:
HOME=/root
LANG (unset)
LANGUAGE (unset)
LC_CTYPE=en_US.UTF-8
LD_LIBRARY_PATH (unset)
LOGDIR (unset)

PATH=/root/s2​:/root/s​:/opt/bin​:/opt/sbin​:/bin​:/sbin​:/usr/bin​:/usr/sbin​:/usr/X11/bin​:/usr/games​:/usr/local/bin​:/usr/local/sbin​:/root/pserv​:.
PERL5LIB=/root/src/sex​:/root/pserv/lib/perl5
PERL5_CPANPLUS_CONFIG=/root/.cpanplus/config
PERLDB_OPTS=ornaments=0
PERL_ANYEVENT_DBI_TESTS=1
PERL_ANYEVENT_LOOP_TESTS=1
PERL_ANYEVENT_NET_TESTS=1
PERL_BADLANG (unset)
PERL_UNICODE=E
SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2014

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2014

From @Leont

On Thu, Jan 16, 2014 at 4​:07 PM, Marc Lehmann <schmorp@​schmorp.de> wrote​:

Things seem more complicated - ExtUtils​::CBuilder actually tries to link
dynamic libraries all the time, even when static linking isn't even
supported by the configuration.

Correct.

The only thing it does reliably is the thing Module​::Build uses it for​:
building dynamically loaded extensions to perl. While it can be used for
other purposes this is increasingly likely to break the further you get
away from a dynamically-loading ELF based Unix system. Quite frankly, I
think everyone who knows CBuilder intimately hate its guts. There's so much
wrong about it that it's practically begging for a rewrite.

I've been meaning to write a minimalistic "can this system compile stuff"
module that doesn't depend on CBuilder. It shouldn't be that difficult, it
just requires rather specialized knowledge that has to be assembled
together.

Leon

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2014

From schmorp@schmorp.de

On Thu, Jan 16, 2014 at 04​:47​:46PM +0100, Leon Timmermans <fawaka@​gmail.com> wrote​:

The only thing it does reliably is the thing Module​::Build uses it for​:
building dynamically loaded extensions to perl. While it can be used for
other purposes this is increasingly likely to break the further you get
away from a dynamically-loading ELF based Unix system. Quite frankly, I
think everyone who knows CBuilder intimately hate its guts. There's so much
wrong about it that it's practically begging for a rewrite.

The problem is that this isn't reflected in the manpage, and it being a
core module, it has crept into lots of modules that think it works (the
same could be said about Module​::Build).

I guess a better solution would be to remove both Module​::Build and
ExtUtils​::Cbuilder from the core - they are obviously not being maintained,
and the visibility their core module status brings with makes them go into
more and more modules instead of less and less.

Maybe for the time being a clear warning in the manpage not to use these
modules in new code would make sense?

I've been meaning to write a minimalistic "can this system compile stuff"
module that doesn't depend on CBuilder. It shouldn't be that difficult, it
just requires rather specialized knowledge that has to be assembled
together.

Thats a great building block, but doesn't solve the larger issue of more
and more of cpan relying on these broken modules.

(As I had to painfully find out over the last week - last year I could
build a lot of cpan without issues, and this year I'm patching stuff for
weeks already, with no end in sight).

--
  The choice of a Deliantra, the free code+content MORPG
  -----==- _GNU_ http​://www.deliantra.net
  ----==-- _ generation
  ---==---(_)__ __ ____ __ Marc Lehmann
  --==---/ / _ \/ // /\ \/ / schmorp@​schmorp.de
  -=====/_/_//_/\_,_/ /_/\_\

@p5pRT
Copy link
Author

p5pRT commented Jan 17, 2014

From @rjbs

* Marc Lehmann <schmorp@​schmorp.de> [2014-01-16T11​:12​:57]

I guess a better solution would be to remove both Module​::Build and
ExtUtils​::Cbuilder from the core - they are obviously not being maintained,
and the visibility their core module status brings with makes them go into
more and more modules instead of less and less.

For the record, Module​::Build is slated for removal in 5.21, but EU​::CB is not.

--
rjbs

@p5pRT
Copy link
Author

p5pRT commented Jan 17, 2014

From @Leont

On Thu, Jan 16, 2014 at 5​:12 PM, Marc Lehmann <schmorp@​schmorp.de> wrote​:

The problem is that this isn't reflected in the manpage, and it being a
core module, it has crept into lots of modules that think it works (the
same could be said about Module​::Build).

It is mentioned as "it is *not* intended as a general cross-platform
interface to all your C building needs", but some of the other text is
encouraging. Problem is that on typical linuxy systems it does work ok for
general C building, so people assume it can do that job everywhere (I've
been guilty of that too at some point).

I guess a better solution would be to remove both Module​::Build and
ExtUtils​::Cbuilder from the core - they are obviously not being maintained,
and the visibility their core module status brings with makes them go into
more and more modules instead of less and less.

Module​::Build is deprecated for 5.20, and will be removed in 5.22 ;-). That
said, it is still maintained by yours truly, most recently by improving
support for Meta 2.0. It has plenty of unresolved issues, but saying it
isn't being maintained at all isn't fair.

As for ExtUtils​::CBuilder, personally I see no reason why it should remain
in core if Module​::Build goes, but I don't think we had consensus on that.

Maybe for the time being a clear warning in the manpage not to use these

modules in new code would make sense?

There are situations where Module​::Build is the only reasonable option, and
there are many simple situations where it doesn't really matter what
install tool you use. All build systems have their advantages and
disadvantages.

Thats a great building block, but doesn't solve the larger issue of more

and more of cpan relying on these broken modules.

That isn't going to change as long as there aren't any alternatives.
Anyway​: https://github.com/Leont/extutils-hascompiler

Leon

@p5pRT
Copy link
Author

p5pRT commented Jan 17, 2014

From schmorp@schmorp.de

On Fri, Jan 17, 2014 at 04​:20​:29AM +0100, Leon Timmermans <fawaka@​gmail.com> wrote​:

It is mentioned as "it is *not* intended as a general cross-platform
interface to all your C building needs",

Well, people use it mostly to detect whether a compiler is available. I
have yte to see it used to actually build something (doubtlessly, that use
exists somewhere too, of course).

Module​::Build is deprecated for 5.20, and will be removed in 5.22 ;-)

That made my day! Probably my year! However... (moved below to the
ExtUTils​::CBuilder discussion).

It's scary how that dependency crept into CPAN in recent years, and that
makes a large share of cpan not buildable on modern multiarch systems
(especially when not using the default configuration). It's a real hold-back
for perl on embedded systems and similar platforms as well. It's probably one
of the reasons we see python on all these platforms but not perl, simply
because it's become almost impossible to use cpan for those anymore.

(https://metacpan.org/requires/module/Module::Build lists 3816 results,
for ExtUtils​::CBuilder "only" 216).

said, it is still maintained by yours truly, most recently by improving
support for Meta 2.0. It has plenty of unresolved issues, but saying it
isn't being maintained at all isn't fair.

Ok... however, to be fair, you must admit that meta 2.0 support isn't
all that important compared to all the breakage this module family
creates. There are well-known build bugs open for half a decade, and I feel I
keep hitting them again and again.

So, while meta 2.0 support might be great progress, it doesn't really feel
like an improvement, or actually making it work even in a basic way.

As it is both Module​::Build and ExtUtils​::CBuilder simply ignore the
perl-provided config and more or less randomly use binary-incompatible
tools, and there seems absolutely no progress there.

So, while it might not be fair, you must admit that calling it
"effectively unmaintained" is pretty much spot on​: It doesn't work, and
it's not getting fixed.

As for ExtUtils​::CBuilder, personally I see no reason why it should remain
in core if Module​::Build goes, but I don't think we had consensus on that.

While it certainly should go, removing it from the core isn't atcually fixing
anything. It does help to ask people to remove the dependency, but that's
just political.

It would be far preferable to make these modules work, at least
rudimentarily.

Maybe for the time being a clear warning in the manpage not to use these

modules in new code would make sense?

There are situations where Module​::Build is the only reasonable option,

I am curious, can you name even one such situation (or even a few?). I
honestly cannot imagine any situation where Module​::Build is the only
reasonable option. I would even go as far nd say it's not a reasonable option
anywhere.

I did hear that Module​::Build is "great" for module authors (I am a module
author and from the docs, it don't know why, but hey, thats fine).

However, I am also from the other side (building perl distros), and for those
poor people who have to suffer form Module​::Build, it's pure hell.

For example, after SDL was switched to Module​::Build there wasn't a SDL
binary build available for windows for two years. I know why, I tried once to
build it for 14 hours.

The design of Module​::Build makes it almost impossible to actually build the
modules, especially on weird platforms such as windows (or anything else I
build on) - if anything goes wrong, you are basically fucked because there is
no way to influence the rather monolithic Module​::Build, no way to edit a
Makefile etc.

If Module​::Build would generate a Makefile.PL by default (something it
can do, but it cannot be done automatically, as far as I know) that would
already help the issue a lot, as I have yet to see a situation where
ExtUtils​::MakeMaker fails in a way that can't be fixed with minimal
effort.

That unfortunately doesn't help for ExtUtils​::CBuilder - I have found that
replacing "have_compiler" with "return 0" works best in practise (return 1
works well, too, but some modules add their own tests that fail much more
miserably when it returns 1, and some, beware, even try to use it to build
stuff).

So a much more preferably (probably in addition) way to actually help the
situation would be to make "have_compiler" actually do as it ays and check
for the availability of the compiler, rather than for the compatibility of
"ld" to whatever compiler and linker is actually configured.

there are many simple situations where it doesn't really matter what
install tool you use. All build systems have their advantages and
disadvantages.

Sure - the disadvantage of Module​::Build and ExtUtils​::CBuilder, however,
is that they don't work as build system on, like, most configs, which
makes them absolute bad, not merely different than others.

Again, for people actually building modules, Module​::Build is pure hell. And
it's been like this for way too many years to claim anything but
"Module​::Build is garbage and needs to die".

Unfortunately, that is also true for ExtUtils​::CBuilder, as it suffers
from the same hardcoded-only-working-on-redhat syndrome.

That isn't going to change as long as there aren't any alternatives.

Well, there are. The easiest alternative the works in 90% of the cases is to
not use these modules. Problem solved. ExtUtils​::MakeMaker more than amply
replaces Module​::Build, and the use cases for ExtUtils​::CBuilder can be
summed up as two cases​:

a) extra check to tell the user that her configuration is broken. that usage
  is just bullshit, and the solution is to simply not do it.
b) check whether a pure perl version is needed or not.

The b) case is valid, but using it for this purpose doesn't work all that
well after all. A proper design would let the user choose.

After all, the systems where you cannot install the proper compiler easily
are waning (it's either apt-get install or it comes with the distro, as
usually on windows these days), and silentlx falling back on a pure-perl
implementation when there is an actual (or imagined!) problem is usually
NOT what people want anyway. (Task​::Weaken is a good lesson here - the
pure perl versions usually do not really replace the xs version, or vice
versa).

Anyway​: https://github.com/Leont/extutils-hascompiler

Might be a good start, but neither "can_compile_executable" nor
"can_compile_loadable_object" are really that useful to have.

Most uses of "have_compiler" are of the form "can I compile an xs
extension?". Neither fo these two functions answre that question.

Do you have an actual use case where one would use
can_compile_loadable_object? Because I can already predict that the same
thing would happen as with ExtUtils​::CBuilder - people will use it to
check whether they can compile xs, and fail otherwise, even if the system
is perfectly capable of compiling their xs module.

To be more precise, the question most people want answered is "will
ExtUtils​::MakeMaker be able to compile my xs code? If not, fall back to
pure-perl". Maybe some want to know "will ExtUtils​::MakeMaker be able to
compile my executable?", which could be covered by can_compile_executable.

Some want the quetsion answered​: "will Module​::Build be able to compile
my xs code?", and tge answer here depends a lot on whether there is a
(non-faked) Makefile.PL or not generated by Module​::Build. If there is,
the questions boil down to the extutils question (and generally chances
will be much improved).

Anyways, I cloned it, and can tell you that can_compile_executable works
well!

As expected (thats true), can_compile_loadable_object works well as well,
except I have no idea what it's usefulness would be. I can imagine some
arcane uses (about the compatibility of two extensions), but I can't see how
can_compile_loadable_object is of help there.

The questions regarding loadable objects mostly boils down to these​:

- when two extensions use the same library, will it be the same (.so)
  or a copy - can_compile_loadable_object cannot answer that.
- can I access symbols exported from another extension (Gtk2 does that)?
  again, can_compile_loadable_object doesn't answer that.

The all important question "can I compile an extension that uses
DynaLoader to load compiled xs code" would be what most people need
answered, but on most distros I have where the answer is true,
can_compile_loadable_object returns 0.

Lastly, I wonder - if you are concerned about these issues, and you
clearly are, why don't you fix some of the most outstanding bugs in e.g.
ExtUtils​::CBuilder? fixing have_compiler would fix a great many modules
without them having to switch.

There are really low-hanging fruit to catch here.

Heck, even something like​:

  sub have_compiler {
  return $ENV{PERL_EXTUTILS_CBUILDER_HAVE_COMPILER}
  of exists $ENV{PERL_EXTUTILS_CBUILDER_HAVE_COMPILER};
  ...

in a cpan-installable ExtUtils​::CBuilder would already be enourmously
helpful (fixing it to give the correct answer in more cases would of
course be even better).

Is there a specific reason to keep the modules in question in broken
state? If there is, I would like to know. Heck, I'd be happy to take over
ExtUtils​::CBuilder if need be. I alwass wanted a module that cna tell me
"reliably" how to do C++ with perl. I'd instantly switch to C++ for most of
my new developments :)

--
  The choice of a Deliantra, the free code+content MORPG
  -----==- _GNU_ http​://www.deliantra.net
  ----==-- _ generation
  ---==---(_)__ __ ____ __ Marc Lehmann
  --==---/ / _ \/ // /\ \/ / schmorp@​schmorp.de
  -=====/_/_//_/\_,_/ /_/\_\

@p5pRT
Copy link
Author

p5pRT commented Jan 17, 2014

From ambs@zbr.pt

A quick pair of cents...

On 17/01/14, 10​:01, Marc Lehmann wrote​:

On Fri, Jan 17, 2014 at 04​:20​:29AM +0100, Leon Timmermans <fawaka@​gmail.com> wrote​:

It is mentioned as "it is *not* intended as a general cross-platform
interface to all your C building needs",

Well, people use it mostly to detect whether a compiler is available. I
have yte to see it used to actually build something (doubtlessly, that use
exists somewhere too, of course).

It is not, but it does a pretty good job on that both for C and C++. I
have modules building complicated libraries using this module, and the
only platform where i have problems is Windows (non-Strawberry windows).

Cheers

@p5pRT
Copy link
Author

p5pRT commented Jan 17, 2014

From @Leont

On Fri, Jan 17, 2014 at 11​:01 AM, Marc Lehmann <schmorp@​schmorp.de> wrote​:

Module​::Build is deprecated for 5.20, and will be removed in 5.22 ;-)

That made my day! Probably my year! However... (moved below to the
ExtUTils​::CBuilder discussion).

It's scary how that dependency crept into CPAN in recent years, and that
makes a large share of cpan not buildable on modern multiarch systems
(especially when not using the default configuration). It's a real
hold-back
for perl on embedded systems and similar platforms as well. It's probably
one
of the reasons we see python on all these platforms but not perl, simply
because it's become almost impossible to use cpan for those anymore.

(https://metacpan.org/requires/module/Module::Build lists 3816 results,
for ExtUtils​::CBuilder "only" 216).

Most of those 216 are probably because Module​::Build used to require one to
add ExtUtils​::CBuilder to build_requires for XS modules. This hasn't been
the case anymore for quite some time AFAIK as Module​::Build always depends
on ExtUtils​::CBuilder nowadays.

Ok... however, to be fair, you must admit that meta 2.0 support isn't
all that important compared to all the breakage this module family
creates.

It is an important feature for many end-users, for example those that want
to install without running tests (not my cup of tea, but if you're
installing Dist​::Zilla on a Raspberry Pi…), who now don't have to install
test dependencies. But there are more uses.

There are well-known build bugs open for half a decade, and I feel I

keep hitting them again and again.

Same could be said for ExtUtils​::MakeMaker actually, though thanks to
BinGOs' efforts its development seems to be regaining momentum.

As it is both Module​::Build and ExtUtils​::CBuilder simply ignore the
perl-provided config and more or less randomly use binary-incompatible
tools, and there seems absolutely no progress there.

So, while it might not be fair, you must admit that calling it
"effectively unmaintained" is pretty much spot on​: It doesn't work, and
it's not getting fixed.

It doesn't work for a fairly tiny minority, but AFAICT it's pretty much
always ExtUtils​::CBuilder that's at fault, not Module​::Build itself. Its
own (plenitude of) flaws lie elsewhere.

It would be far preferable to make these modules work, at least

rudimentarily.

Obviously.

I am curious, can you name even one such situation (or even a few?). I

honestly cannot imagine any situation where Module​::Build is the only
reasonable option. I would even go as far nd say it's not a reasonable
option
anywhere.

You can write extensions in Module​::Build entirely in Perl, which you
generally can't in MakeMaker.

I did hear that Module​::Build is "great" for module authors (I am a module

author and from the docs, it don't know why, but hey, thats fine).

IME writing a *good*, correct and backwards compatible Makefile.PL is can
be rather a PITA, and anyone I know who does that just copies an existing
one and adapts the prereqs/meta-information instead of writing it from
scratch. I only started using ExtUtils​::MakeMaker myself when dzil started
generating it for me.

For example, after SDL was switched to Module​::Build there wasn't a SDL

binary build available for windows for two years. I know why, I tried once
to
build it for 14 hours.

The design of Module​::Build makes it almost impossible to actually build
the
modules, especially on weird platforms such as windows (or anything else I
build on) - if anything goes wrong, you are basically fucked because there
is
no way to influence the rather monolithic Module​::Build, no way to edit a
Makefile etc.

If Module​::Build would generate a Makefile.PL by default (something it
can do, but it cannot be done automatically, as far as I know) that would
already help the issue a lot, as I have yet to see a situation where
ExtUtils​::MakeMaker fails in a way that can't be fixed with minimal
effort.

I agree that is a problem, but again the real issue is in
ExtUtils​::CBuilder. It doesn't expose the information that would be
necessary to do what you want to do. I consider that the #1 reason for
calling ExtUtils​::CBuilder unsalvageable, fixing that would essentially be
rewriting it from scratch IMO.

That unfortunately doesn't help for ExtUtils​::CBuilder - I have found that
replacing "have_compiler" with "return 0" works best in practise (return 1
works well, too, but some modules add their own tests that fail much more
miserably when it returns 1, and some, beware, even try to use it to build
stuff).

So a much more preferably (probably in addition) way to actually help the
situation would be to make "have_compiler" actually do as it ays and check
for the availability of the compiler, rather than for the compatibility of
"ld" to whatever compiler and linker is actually configured.

Patches welcome. Honestly, you're probably the person here with most
experience with non-dynamic perls.

Sure - the disadvantage of Module​::Build and ExtUtils​::CBuilder, however,

is that they don't work as build system on, like, most configs, which
makes them absolute bad, not merely different than others.

They do work on most configurations, or else perl couldn't ship with it.
That doesn't mean your bug isn't real, but it's more limited that you're
suggesting here.

Again, for people actually building modules, Module​::Build is pure hell.
And
it's been like this for way too many years to claim anything but
"Module​::Build is garbage and needs to die".

Actually I would like to see Module​::Build gone, but for subtly different
reasons than you I suspect.

Well, there are. The easiest alternative the works in 90% of the cases is
to
not use these modules. Problem solved. ExtUtils​::MakeMaker more than amply
replaces Module​::Build, and the use cases for ExtUtils​::CBuilder can be
summed up as two cases​:

a) extra check to tell the user that her configuration is broken. that
usage
is just bullshit, and the solution is to simply not do it.
b) check whether a pure perl version is needed or not.

The b) case is valid, but using it for this purpose doesn't work all that
well after all. A proper design would let the user choose.

We conceived PUREPERL_ONLY/--pureperl_only at last year's QA Hackathon, but
it's not in very wide use yet.

After all, the systems where you cannot install the proper compiler easily
are waning (it's either apt-get install or it comes with the distro, as
usually on windows these days), and silentlx falling back on a pure-perl
implementation when there is an actual (or imagined!) problem is usually
NOT what people want anyway. (Task​::Weaken is a good lesson here - the
pure perl versions usually do not really replace the xs version, or vice
versa).

Many cheap hosting companies don't supply a compiler :-(.

Anyway​: https://github.com/Leont/extutils-hascompiler

Might be a good start, but neither "can_compile_executable" nor
"can_compile_loadable_object" are really that useful to have.

Most uses of "have_compiler" are of the form "can I compile an xs
extension?". Neither fo these two functions answre that question.

Well, it's just something I hacked up last night, it's quite far from being
done.

Do you have an actual use case where one would use
can_compile_loadable_object? Because I can already predict that the same
thing would happen as with ExtUtils​::CBuilder - people will use it to
check whether they can compile xs, and fail otherwise, even if the system
is perfectly capable of compiling their xs module.

To be more precise, the question most people want answered is "will
ExtUtils​::MakeMaker be able to compile my xs code? If not, fall back to
pure-perl". Maybe some want to know "will ExtUtils​::MakeMaker be able to
compile my executable?", which could be covered by can_compile_executable.

That's why I called it can_compile_loadable_object and not have_compiler or
can_compile_perl_extension ;-).

Some want the quetsion answered​: "will Module​::Build be able to compile
my xs code?", and tge answer here depends a lot on whether there is a
(non-faked) Makefile.PL or not generated by Module​::Build. If there is,
the questions boil down to the extutils question (and generally chances
will be much improved).

Anyways, I cloned it, and can tell you that can_compile_executable works
well!

As expected (thats true), can_compile_loadable_object works well as well,
except I have no idea what it's usefulness would be. I can imagine some
arcane uses (about the compatibility of two extensions), but I can't see
how
can_compile_loadable_object is of help there.

It's mostly a step towards can_compile_perl_extension.

The all important question "can I compile an extension that uses

DynaLoader to load compiled xs code" would be what most people need
answered, but on most distros I have where the answer is true,
can_compile_loadable_object returns 0.

Is that on static perls (where it should be false), or on dynamic perls?

Lastly, I wonder - if you are concerned about these issues, and you

clearly are, why don't you fix some of the most outstanding bugs in e.g.
ExtUtils​::CBuilder? fixing have_compiler would fix a great many modules
without them having to switch.

There are really low-hanging fruit to catch here.

Because I consider it unsalvageable​: I'd rather spend time on writing a
framework that can be used in other contexts than Module​::Build such as
inside Makefiles, that is general-purpose enough to be used for other
things than perl extensions such as executables and libraries and that is
tied less to perl's configuration. Which unfortunately is a rather
ambitious goal and not something I expect to finish very soon.

Another part of your particular issue is that there's no documentation on
what it should do. Fixing it involves building a static perl,
reverse-engineering what MakeMaker does on it and why, and then trying to
fit that into the existing interface.

I might actually fix this given how much depends on it, but hateful code is
hateful.

Heck, even something like​:

sub have_compiler {
return $ENV{PERL_EXTUTILS_CBUILDER_HAVE_COMPILER}
of exists $ENV{PERL_EXTUTILS_CBUILDER_HAVE_COMPILER};
...

in a cpan-installable ExtUtils​::CBuilder would already be enourmously
helpful (fixing it to give the correct answer in more cases would of
course be even better).

Seems reasonable.

Is there a specific reason to keep the modules in question in broken
state? If there is, I would like to know. Heck, I'd be happy to take over
ExtUtils​::CBuilder if need be. I alwass wanted a module that cna tell me
"reliably" how to do C++ with perl. I'd instantly switch to C++ for most of
my new developments :)

There is no specific reason. It's really that it isn't getting any love
unless it's actively breaking something for someone motivated.

Leon

@p5pRT
Copy link
Author

p5pRT commented Jan 22, 2014

From schmorp@schmorp.de

On Fri, Jan 17, 2014 at 06​:27​:51PM +0100, Leon Timmermans <fawaka@​gmail.com> wrote​:

Ok... however, to be fair, you must admit that meta 2.0 support isn't
all that important compared to all the breakage this module family
creates.

It is an important feature for many end-users, for example those that want
to install without running tests (not my cup of tea, but if you're

I install without running tetss by default (as my experience is that
requiring tests makes almost every module uninstallable), and I am sure I
don't need meta 2.0 support for that.

installing Dist​::Zilla on a Raspberry Pi…), who now don't have to install
test dependencies.

I'd gladly install test dependencies (in fact, I currently have to, as
Module​::Build fails when installing them itself) if only that gave me a
working module in the end.

But there are more uses.

But apparently none as important as actually making the module compile and
install.

There are well-known build bugs open for half a decade, and I feel I

keep hitting them again and again.

Same could be said for ExtUtils​::MakeMaker actually

Possibly, but ExtUtils​::MakeMaker never kept me from having a module actually
install on any platform, be it some fluffy GNU/Linux, some stone-age HP-UX,
my N900 phone or windows.

I think the majore thing that ExtUtils​::MakeMaker has in it's favour is that
it is configurable and actually honors the perl configuration itself.

It's not at all uncommon to have to have some adjustments for some build
environments - ExtUtils​::MakeMaker uses these as perl istefl does.

BinGOs' efforts its development seems to be regaining momentum.

Yes, but even before, ExtUtils​::MakeMaker never was even near as
problematuic and broken as Module​::Buiold was during it's whole lifetime.

So, while it might not be fair, you must admit that calling it
"effectively unmaintained" is pretty much spot on​: It doesn't work, and
it's not getting fixed.

It doesn't work for a fairly tiny minority,

For some reason, all my platforms seem to be "in the minority". I cannot
quite accept that.

I am curious, can you name even one such situation (or even a few?). I

honestly cannot imagine any situation where Module​::Build is the only
reasonable option. I would even go as far nd say it's not a reasonable
option
anywhere.

You can write extensions in Module​::Build entirely in Perl, which you
generally can't in MakeMaker.

I am not sure what that means - all of my pure-perl extensions are using
ExtUtils​::MakeMaker, and every time I ever wanted to extend
ExtUtils​::MakeMaker I could do that entirely in Perl.

IME writing a *good*, correct and backwards compatible Makefile.PL is can
be rather a PITA,

True, but unlike with Module​::Build, it's at least possible.

Trying the same with Module​::Build generally results in basically
rewriting all the build and link code to work around Module​::Build - ask
the SDL people, who really like Module​::Build, and tried to actually make
it work after I reported a few bugs, and gave up weeks later.

I know it's just me, but I choose difficult-but-possible over
simple-but-impossible any day.

I agree that is a problem, but again the real issue is in
ExtUtils​::CBuilder. It doesn't expose the information that would be
necessary to do what you want to do.

All cases I stumble over are have_compiler return false when
ExtUtils​::MakeMaker can do it on the same system without any hiccups.

I really don't care how ell it is designed, but the main problem w.r.t.
cpan breakage is not that it doesn't expose enough information, but that
it simply returns the wrong answers (such as false from have_compiler).

I consider that the #1 reason for calling ExtUtils​::CBuilder
unsalvageable, fixing that would essentially be rewriting it from
scratch IMO.

I am quite sure one can fix have_compiler and a lot more without rewriting
it from scratch. Just forcing that method to return true makes almost
everything that depends on it (and that I wantt to install) actually
compile and install - and the few cases that don't are not usually due to
ExtUtils​::CBuilder.

As long as ExtUtils​::CBuilder doesn't even do what it documents to do, it's
going to create more problems.

So at the very least, the documentation should have some big "WARNING​: this
module is broken and does NOT do what it claims to do, do NOT use it" or so
at the top.

That would make it much easier to get cpan authors to actually fix their
modules - I often get told (not quite incorrectly) that they rely on
ExtUtils​::CBuilder so the bug needs to be fixed there.

So there is a classical catch 22 - module authors rely on ExtUtils​::CBuilder
because it's an official module with wrong documentation (or, preferably,
broken implementation), and the ExtUtils​::CBuilder maintainers keep the
status quo.

One side has to give - either deprecate ExtUtils​::CBuilder *officially*
and document that it doesn't work so we can get CPAN authors to fix their
modules, or fix ExtUtils​::CBuilder.

Saying it's badly designed but at the same time claiming it works when it
doesn't is a no-go.

So a much more preferably (probably in addition) way to actually help the
situation would be to make "have_compiler" actually do as it ays and check
for the availability of the compiler, rather than for the compatibility of
"ld" to whatever compiler and linker is actually configured.

Patches welcome. Honestly, you're probably the person here with most
experience with non-dynamic perls.

As if the problem happens only with non-dynamic perls.

I'll think about a patch - however, if ExtUtils​::CBuilder is supposed to
die anyway, then I will probably go for a documentation patch + a manual
override (like, say, an environment variable).

Sure - the disadvantage of Module​::Build and ExtUtils​::CBuilder, however,

is that they don't work as build system on, like, most configs, which
makes them absolute bad, not merely different than others.

They do work on most configurations,

Not in my experience.

or else perl couldn't ship with it.

Perl as shipped usually only builds cleanly on a few platforms.

I think you confuse "most platforms" with "most gnu/linux distributions in
their default config".

That doesn't mean your bug isn't real, but it's more limited that you're
suggesting here.

As it is, Module​::Build/ExtUtils​::CBuilder don't work on GNU/Linux and
Windows, the platforms I most often build with, with my default config (32
bit ints on x86, custom optimsiation flags, custom library paths, disabled
threads/multiplicity).

If I only had problems with static linking I could understand your
judgement.

Actually I would like to see Module​::Build gone, but for subtly different
reasons than you I suspect.

Very likely - I don't want to see it gone as much as I would like to see it
just working. I have zero issues with CPAN authors wanting to use it because
they prefer it over ExtUtils​::MakeMaker, and I wouldn't even exclude me fromt
hat group.

The reason I want tos ee it gone is that I don't see it gettting fixed
anytime soon, while at the same time it's infecting mroe and mroe of CPAN
with its breakage.

a) extra check to tell the user that her configuration is broken. that
usage
is just bullshit, and the solution is to simply not do it.
b) check whether a pure perl version is needed or not.

The b) case is valid, but using it for this purpose doesn't work all that
well after all. A proper design would let the user choose.

We conceived PUREPERL_ONLY/--pureperl_only at last year's QA Hackathon, but
it's not in very wide use yet.

If that means using an env variable or switch, then I'd say it's a
non-starter​: I'd love to have this, but when I suggested something like that
to some module authors I was told that they will always prefer autodetection,
because on "modern systems" it's common to not have a compiler.

Maybe that's just a minority, but unfortunately, some CPAN authors want to
be helpful and grasp at every hack they can find that allows them to get
greener status on cpantesters, no matter how much more difficult it makes
their module to build in general.

implementation when there is an actual (or imagined!) problem is usually
NOT what people want anyway. (Task​::Weaken is a good lesson here - the
pure perl versions usually do not really replace the xs version, or vice
versa).

Many cheap hosting companies don't supply a compiler :-(.

Looking at the prices for virtual hosting, I am not sure the price is the
deciding factor these days.

Whats more, Debian GNU/Linux and Fedora (and most other GNU/Linux distros) do
not supply a compiler either, and installing one is as hard for users as for
those hosting solutions.

So, since this is a real problem, module authors will want to go for
pureperl variants, and autodetection (the greener pastures...).

Do you have an actual use case where one would use
can_compile_loadable_object? Because I can already predict that the same
thing would happen as with ExtUtils​::CBuilder - people will use it to
check whether they can compile xs, and fail otherwise, even if the system
is perfectly capable of compiling their xs module.

To be more precise, the question most people want answered is "will
ExtUtils​::MakeMaker be able to compile my xs code? If not, fall back to
pure-perl". Maybe some want to know "will ExtUtils​::MakeMaker be able to
compile my executable?", which could be covered by can_compile_executable.

That's why I called it can_compile_loadable_object and not have_compiler or
can_compile_perl_extension ;-).

You called it thsat wa ybecause you do not want to answre the common
question that users will have for your module? I can't quite follow _that_
logic.

I am still quite intereste din a usecase for can_compile_loadable_object -
it seems to be quite esoteric.

Anyways, I cloned it, and can tell you that can_compile_executable works
well!

As expected (thats true), can_compile_loadable_object works well as well,
except I have no idea what it's usefulness would be. I can imagine some
arcane uses (about the compatibility of two extensions), but I can't see
how
can_compile_loadable_object is of help there.

It's mostly a step towards can_compile_perl_extension.

But can_compile_perl_extension does not rely on
can_compile_loadable_object at all.

The all important question "can I compile an extension that uses

DynaLoader to load compiled xs code" would be what most people need
answered, but on most distros I have where the answer is true,
can_compile_loadable_object returns 0.

Is that on static perls (where it should be false), or on dynamic perls?

static perls (I maintain 4 dynamic distros and 9 static ones at the
moment).

(as a sidenote, the distinction is between static extensions and dynamic
ones - "static perls" are just perls that cannot grok dynamic ones, static
extensions work on dynamic perls).

however, is it really clearly defined what a "loadable object"
is? Defining it as a ELF shared object (for example) would clearly be too
narrow, while defining it as "anything DynaLoader/XSLoader can load" might
be too wide (as they work for statically linked-in extensions).

ExtUtils​::CBuilder? fixing have_compiler would fix a great many modules
without them having to switch.

There are really low-hanging fruit to catch here.

Because I consider it unsalvageable

Would you accept a doc patch that officiall deprecates the module,
recommends to not use it, and documents some of the more obvious
shortcomings?

framework that can be used in other contexts than Module​::Build such as
inside Makefiles, that is general-purpose enough to be used for other
things than perl extensions such as executables and libraries and that is
tied less to perl's configuration. Which unfortunately is a rather
ambitious goal and not something I expect to finish very soon.

Not just that, adding more frameworks makes the problem worse, not better -
the old broken frameworks don't go away, and the new frameworks are not yet
stable.

No issue if you actively maintain such frameworks, but as Module​::Build
shows, things cna go wrong when you release a build framework in beta
status and then never make it work.

Another part of your particular issue is that there's no documentation on
what it should do.

I know a lot of ways to detect the presence of the configured compiler and
linker without linking a perl (which isn't that hard, perl comes with all
the necessary glue, mostly ExtUtils​::{Liblist,MakeMaker,Miniperl}).

A simple way would be for the existance of the programs themselves. That would
work for a lot of simple cases, and probably all of the relevant one (cheap
hosters, gnu/linux distros without gcc).

I wouldn't work correctly when your compiler is "ccache gcc" (as it often
is for me), but that doesn't actually seem to be the relevant case (I am
sure if I complained about that one I would get told the same thing as
now​: "that is a not an important case, too bad for you", and I wouldn't
even report that, as I can easily fix that myself).

If that isn't enough, indeed linking an extension the way MakeMaker
would do it (I don't think it involves much more than some config var
collection) would probably be nore enough.

I mean, do you want to answer "system has a compiler" as documented, or do
you want to answer "will my extension build". The latter cannot ever be
solved with any test, short of doing the whole thing and seeing whether
that works.

Heck, even something like​:

sub have_compiler {
return $ENV{PERL_EXTUTILS_CBUILDER_HAVE_COMPILER}
of exists $ENV{PERL_EXTUTILS_CBUILDER_HAVE_COMPILER};
...

in a cpan-installable ExtUtils​::CBuilder would already be enourmously
helpful (fixing it to give the correct answer in more cases would of
course be even better).

Seems reasonable.

I can send a patch - any suggestions for the name of the variable? (my
naming scheme is always perl + extension name + whatever, but no other
module I know does that :)

--
  The choice of a Deliantra, the free code+content MORPG
  -----==- _GNU_ http​://www.deliantra.net
  ----==-- _ generation
  ---==---(_)__ __ ____ __ Marc Lehmann
  --==---/ / _ \/ // /\ \/ / schmorp@​schmorp.de
  -=====/_/_//_/\_,_/ /_/\_\

@p5pRT
Copy link
Author

p5pRT commented Jan 22, 2014

From schmorp@schmorp.de

BTW, yes, you can also load modules dynamically in static perls - the
concepts are really orthogonal.

In any case, a point I wanted to make clear is that I do not expect perl to
build out of the box perfectly in every situation. It never did, and never
will, and that's ok.

My concern is being able to work around any issues. For example,
App​::Staticperl adds four patches (see below for details) - one teaches
CPAN to not clobber the users config file (shocking that you have to patch
it to do that), one works around some issue when bulding Gtk2/Pango that
I haven't fully investigated, one works around the issue of Miniperl not
including DynaLoader in static perls even though it should, and one makes
have_compiler always return 0.

The first three are relatively minor in effect. The last one is brutal,
mostly because have_compiler returning 0 generates more success then
having it return 1, and fixing the remaining parts of Module​::Build and
especially ExtUtils​::CBuilder can't be done with a simialrly simple
one-line hack as the others.

So, all I would be asking fro is to not have a totally hardwired
uncontrollable configuration, as is currently the case with both
Module​::Build and ExtUtils​::Cbuilder.

Being able to trickle out a (full) Makefile.PL in a generic way from a
Build.PL would go a long way towards this goal - Module​::Build cna do it, but
I haven't found a way to automatically do it without understanding sand
patching the Build.PL script.

  # patch CPAN​::HandleConfig.pm to always include _our_ MyConfig.pm,
  # not the one in the users homedirectory, to avoid clobbering his.
  patch CPAN/HandleConfig.pm cpan_handleconfig_pm '
  1i\
  use CPAN​::MyConfig; # patched by staticperl
  '

  # patch ExtUtils​::MM_Unix to always search blib for modules
  # when building a perl - this works around Pango/Gtk2 being misdetected
  # as not being an XS module.
  patch ExtUtils/MM_Unix.pm mm_unix_pm '
  /^sub staticmake/,/^}/ s/if (@​{$self->{C}}) {/if (@​{$self->{C}} or $self-&gt;{NAME} =~ m%^(Pango|Gtk2)$%) { # patched by staticperl/
  '

  # patch ExtUtils​::Miniperl to always add DynaLoader
  # this is required for dynamic loading in static perls,
  # and static loading in dynamic perls, when rebuilding a new perl.
  # Why this patch is necessray I don't understand. Yup.
  patch ExtUtils/Miniperl.pm extutils_miniperl.pm '
  /^sub writemain/ a\
  push @​_, canon("/","DynaLoader"); # patched by staticperl
  '

  # ExtUtils​::CBuilder always tries to link shared libraries
  # even on systems without shared library support. [...]
  # [...] since so many dependent modules are even worse,
  # we hardwire to 0 to get their pure-perl versions.
  patch ExtUtils/CBuilder/Base.pm extutils_cbuilder_base.pm '
  /^sub have_compiler/ a\
  return 0; # patched by staticperl
  '

--
  The choice of a Deliantra, the free code+content MORPG
  -----==- _GNU_ http​://www.deliantra.net
  ----==-- _ generation
  ---==---(_)__ __ ____ __ Marc Lehmann
  --==---/ / _ \/ // /\ \/ / schmorp@​schmorp.de
  -=====/_/_//_/\_,_/ /_/\_\

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants