Re: How to best detect availability of C compiler in Makefile.PL?
[sorry, I cc'd the wrong address... corrected.] At 10AM +0100 on 3/11/09 you (O. STeffen BEYer) wrote: 2009/11/3 Ben Morrow b...@morrow.me.uk Instead, just assume the default answer *without* stopping, and use an environment variable to allow the user to tweak the answer if they need to. You can print a message like Using the XS version since I found a compiler in /usr/bin/gcc: set PERL_DATE_CALC_NOXS=1 in the environment and re-run Makefile.PL to override this choice. if you think users who might want to choose won't read the README. Is there any standard environment variable for this sort of thing? Actually, there is an environment variable foreseen by MakeMaker (see below)! PERL_MM_USE_DEFAULT This is not quite what I meant. MM_USE_DEFAULT will cause prompt to take the default action, which is fine if that is what the user wants. I am suggesting using PERL_DATE_CALC_NOXS as a way to *change* the default without having to answer the question. IMHO prompt() is nearly always a mistake. (Asking question by other means is *more* of a mistake, of course :).) Ben
Re: How to best detect availability of C compiler in Makefile.PL?
* O. STeffen BEYer ost...@gmail.com [2009-10-13 15:30]: I'd rather have the user decide what he/she wants, as in this attached file. That’s the wrong way to think about it. OK, hyperbole; it’s not *wrong*. But it’s very incomplete. Don’t forget that there are a lot of people who might merely want to use some Perl program, and unlike you and me, they *aren’t* Perl programmers. They are merely users of some random Perl code that uses your module. Most of these users don’t care which version of your module gets installed, and if you ask them to pick one anyway, they won’t know how to decide, either. All they know is they want the program they care about to work. To these people, the option you want to offer is not helpful. It is, in fact, a bewildering obstacle. So for them, you have to provide sensible defaults for all options. (And if there isn’t any strong reason to offer an option in the first place, it shouldn’t even be an option. But that’s just a sidenote, since in your case there is solid reason.) That means your module should just check for a compiler and install with the XS variant by default if possible. The option to change that should be provided in such a way that opinionated users can get at it without forcing other users to care. (This is probably best achieved by checking some environment variable in your *.PL, since that passes down easily through the CPAN shell, whereas taking a switch would force more manual monkeying.) * O. STeffen BEYer ost...@gmail.com [2009-10-13 23:05]: Since Date::Calc is such a low-level basic module, it should be especially backward compatible, so that even people in old production environments (never fix what ain't broken) can upgrade my module and benefit from new functions, without having to install a load of other modules first - which their company policies would probably not permit. If they can install Date::Calc, how come they can’t or won’t install other modules? OK, maybe they can’t install XS modules. I can see that. But if they can install *your* pure-Perl module, why can’t they install other pure-Perl modules also? This is not the first time I see this argument and I never understood it. *headscratch* Regards, -- Aristotle Pagaltzis // http://plasmasturm.org/
Re: How to best detect availability of C compiler in Makefile.PL?
Hello Aristotle, I'll answer below: 2009/11/3 Aristotle Pagaltzis pagalt...@gmx.de * O. STeffen BEYer ost...@gmail.com [2009-10-13 15:30]: I'd rather have the user decide what he/she wants, as in this attached file. That’s the wrong way to think about it. OK, hyperbole; it’s not *wrong*. But it’s very incomplete. Don’t forget that there are a lot of people who might merely want to use some Perl program, and unlike you and me, they *aren’t* Perl programmers. They are merely users of some random Perl code that uses your module. Most of these users don’t care which version of your module gets installed, and if you ask them to pick one anyway, they won’t know how to decide, either. All they know is they want the program they care about to work. To these people, the option you want to offer is not helpful. It is, in fact, a bewildering obstacle. Yes, I agree. This is one of the reasons why I have adopted the common approach of Date::Calc being the pure Perl module, and Date::Calc::XS the plug-in needing a C compiler. Another reason was that you would not know which version had been tested in CPAN::Testers. And still another reason was that when giving support, it would be extremely hard to find out which version the user was using. I would have needed the user to jump through hoops to get this information. So for them, you have to provide sensible defaults for all options. (And if there isn’t any strong reason to offer an option That was actually the case (or is - see version 6.1 of Date::Calc!). The presence of a suitable compiler was determined, and then Makefile.PL explicitly said what was recommended. By just hitting Return, the user would get the recommended option. in the first place, it shouldn’t even be an option. But that’s just a sidenote, since in your case there is solid reason.) That means your module should just check for a compiler and install with the XS variant by default if possible. The option to change that should be provided in such a way that opinionated users can get at it without forcing other users to care. (This is probably best achieved by checking some environment variable in your *.PL, since that passes down easily through the CPAN shell, whereas taking a switch would force more manual monkeying.) * O. STeffen BEYer ost...@gmail.com [2009-10-13 23:05]: Since Date::Calc is such a low-level basic module, it should be especially backward compatible, so that even people in old production environments (never fix what ain't broken) can upgrade my module and benefit from new functions, without having to install a load of other modules first - which their company policies would probably not permit. If they can install Date::Calc, how come they can’t or won’t install other modules? OK, maybe they can’t install XS modules. I can see that. But if they can install *your* pure-Perl module, why can’t they install other pure-Perl modules also? This is not the first time I see this argument and I never understood it. *headscratch* Sometimes they can get permission for one module, or at least a well-defined list of a few modules, but not for an endless list of modules and dependencies (which the user frequently does not know exactly in advance). And permission does not mean that they can install the module(s) themselves, no, it means that the administrator is going to install the module(s) for them. So the less work this administrator has to do, the more likely to get his/her permission (if he/she has the power to decide that, as is sometimes the case in certain companies). And it may be even more difficult to get permission from a manager who hasn't a clue what the user is talking about, and the less the manager sees a security risk, the better. So the fewer modules, the better. Do you understand it now? :-) Best regards, Steffen
Re: How to best detect availability of C compiler in Makefile.PL?
On Tue, Oct 13, 2009 at 11:01:56PM +0200, O. STeffen BEYer wrote: Also, many of your suggestions need Perl modules to be installed on the target machine which do not exist on legacy Perl installations ... Devel::CheckLib is designed to be bundled with your distribution. -- David Cantrell | top google result for internet beard fetish club You know you're getting old when you fancy the teenager's parent and ignore the teenager -- Paul M in uknot
Re: How to best detect availability of C compiler in Makefile.PL?
Hello David, yes, I had understood that, but I failed to be more explicit about the problems with legacy platforms: Often, newer modules are not installed on them, AND/OR newer modules may not even work on legacy platforms due to their using Perl features which are newer and not available on older platforms. For instance, I am regularly testing all my modules with Perl 5.005_03 before each release. And they still work on it. Out of the box. Cheers, Steffen P.S.: In the meantime, I have adopted the proposed solution with ExtUtils::CBuilder. See also the attached Makefile.PL. 2009/10/14 David Cantrell da...@cantrell.org.uk On Tue, Oct 13, 2009 at 11:01:56PM +0200, O. STeffen BEYer wrote: Also, many of your suggestions need Perl modules to be installed on the target machine which do not exist on legacy Perl installations ... Devel::CheckLib is designed to be bundled with your distribution. -- David Cantrell | top google result for internet beard fetish club You know you're getting old when you fancy the teenager's parent and ignore the teenager -- Paul M in uknot Makefile.PL Description: Binary data
How to best detect availability of C compiler in Makefile.PL?
Dear Perl module authors, what would be the best way to detect whether a working C compiler is available at build time of a module (i.e., in Makefile.PL)? I would like to install a (faster) XS version of a module if that is the case, and a (slower) pure-Perl implementation if not. Remember that C compilers are not always available on all systems. Sometimes they cost heavy extra money, or sometimes you have to work with what's there on a customer's or provider's server (where frequently installing a C compiler is not an option due to company policies). Thank you! Best regards, Steffen Beyer http://www.engelschall.com/u/sb/download/ http://search.cpan.org/author/STBEY
Re: How to best detect availability of C compiler in Makefile.PL?
On Tuesday 13 October 2009 06:17:47 O. STeffen BEYer wrote: Dear Perl module authors, what would be the best way to detect whether a working C compiler is available at build time of a module (i.e., in Makefile.PL)? I would like to install a (faster) XS version of a module if that is the case, and a (slower) pure-Perl implementation if not. Remember that C compilers are not always available on all systems. Sometimes they cost heavy extra money, or sometimes you have to work with what's there on a customer's or provider's server (where frequently installing a C compiler is not an option due to company policies). While I've got no idea about detecting the compiler, I would suggest though installing the pure perl one no matter what, under a different name and having the module fall back on it if possible, that way if something changes later on the module will always continue to work. This could also simplify the build and install process since you wouldn't have to decide which one to copy during make install.
Re: How to best detect availability of C compiler in Makefile.PL?
Hi Ryan, thanks a lot for your fast response (see a copy at the bottom of this message for convenience)! But how would I then test both module versions (Date::Calc and Date::Pcalc) with the same test suite, without duplicating code? And how would I rely on the Perl version in the C/XS version if something goes wrong? Something along these lines? package Date::Calc; BEGIN { eval { require bytes; }; } use strict; use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION); @ISA = qw(Exporter DynaLoader); @EXPORT = qw(); @EXPORT_OK = qw( ... ); %EXPORT_TAGS = (all = [...@export_ok]); $VERSION = '6.1'; BEGIN # otherwise this comes too late for imports from this module { require Exporter; require DynaLoader; eval { bootstrap Date::Calc $VERSION; }; if ($@) { local($^W) = 0; # avoid subroutine redefined warnings for the three subroutines below eval { require Date::Pcalc; Date::Pcalc-import(':all'); }; if ($@) { die Can't find neither the dynamically loadable library for Date::Calc nor its pure-Perl substitute Date::Pcalc!\n; } else { warn Unable to find the dynamically loadable library for Date::Calc, falling back to its pure-Perl substitute Date::Pcalc!\n; } } } sub Decode_Date_EU2 { ... Another thing I am wondering about: You wrote: if something changes later on the module will always continue to work I am wondering _what_ could change later (or go wrong), and if it would be the right thing to do to (silently?) fall back to the pure-Perl version - maybe even without a warning to the user. If the Calc.dll (or shared library Calc.so) disappears, this almost certainly indicates that there is something seriously wrong, which should be cried about loud and fixed before continuing. Or if somebody installs a newer Perl version over an existing one, this could break binary compatibiliy. But I wonder if the eval bootstrap above would be able to catch that. Anyway: In the meantime, I found a way how to detect the compiler in Inline.pm. See the attached Makefile.PL to see how this would work with Date::Calc. I am reluctant to install the Perl version no matter what, as you suggested; I'd rather have the user decide what he/she wants, as in this attached file. Any opinions on all this, anyone? Cheers, Steffen 2009/10/13 Ryan Voots simcop2...@yahoo.com On Tuesday 13 October 2009 06:17:47 O. STeffen BEYer wrote: Dear Perl module authors, what would be the best way to detect whether a working C compiler is available at build time of a module (i.e., in Makefile.PL)? I would like to install a (faster) XS version of a module if that is the case, and a (slower) pure-Perl implementation if not. Remember that C compilers are not always available on all systems. Sometimes they cost heavy extra money, or sometimes you have to work with what's there on a customer's or provider's server (where frequently installing a C compiler is not an option due to company policies). While I've got no idea about detecting the compiler, I would suggest though installing the pure perl one no matter what, under a different name and having the module fall back on it if possible, that way if something changes later on the module will always continue to work. This could also simplify the build and install process since you wouldn't have to decide which one to copy during make install. Makefile.PL Description: Binary data
Re: How to best detect availability of C compiler in Makefile.PL?
On Tue, Oct 13, 2009 at 6:17 AM, O. STeffen BEYer ost...@gmail.com wrote: what would be the best way to detect whether a working C compiler is available at build time of a module (i.e., in Makefile.PL)? See the Makefile.PL for the 'threads' module. I have reused this technique in several other modules and it works well.
Re: How to best detect availability of C compiler in Makefile.PL?
On Tue, Oct 13, 2009 at 9:29 AM, O. STeffen BEYer ost...@gmail.com wrote: Hi Ryan, thanks a lot for your fast response (see a copy at the bottom of this message for convenience)! See also Devel::CheckLib, which can check for a compiler for you (just don't specify a lib) and has a handy command line utility to bundle itself in inc/ and add itself to your *.PL file. But how would I then test both module versions (Date::Calc and Date::Pcalc) with the same test suite, without duplicating code? See Test::NoXS, which disables dynamic loading. I would put the tests into functions in a utility module in t/ and have separate .t files for XS and PP. The PP one should use Test::NoXS (with your module name as an argument), then load your module, then run the tests from your utility module. And how would I rely on the Perl version in the C/XS version if something goes wrong? Something along these lines? Pretty much. I'd suggest copying what List::Util does. -- David
Re: How to best detect availability of C compiler in Makefile.PL?
On Tue, Oct 13, 2009 at 10:12:41AM -0400, Jerry D. Hedden wrote: On Tue, Oct 13, 2009 at 6:17 AM, O. STeffen BEYer ost...@gmail.com wrote: what would be the best way to detect whether a working C compiler is available at build time of a module (i.e., in Makefile.PL)? See the Makefile.PL for the 'threads' module. I have reused this technique in several other modules and it works well. If all you need is a compiler, then that's the way to go. If what you want to do is compile some stuff and link it to some other stuff, then I'd use Devel::CheckLib, which will check for both a compiler, the necessary libraries/headers, and a working linker. -- David Cantrell | Official London Perl Mongers Bad Influence [OS X] appeals to me as a monk, a user, a compiler-of-apps, a sometime coder, and an easily amused primate with a penchant for those that are pretty, colorful, and make nice noises. -- Dan Birchall, in The Monastery
Re: How to best detect availability of C compiler in Makefile.PL?
I think ExtUtils::CBuilder is useful for detecting the presence of a compiler. It has a have_compiler method that tells you whether a compiler is present (by actually trying to compile a C file). For more advanced uses, something like the aforementioned Devel::CheckLib will probably be of great help. What I've done (so that users have a choice) is provide alternate implementations using Pure Perl and XS, and then have the Perl version load the XS one if it's available (using eval { require ... }) It's good because a) Lots of modules already do this b) It means updates to one (say, fixing a bug in the Perl version) doesn't require re-releasing of both c) It means if someone has a C builder present but wants to use the Perl version anyway (for whatever reason), they can do so. You can look into Math::Random::ISAAC (pure perl) and Math::Random::ISAAC::XS for these. The code is rather small. On the other hand lots of other packages (version.pm for example) do the whole Perl/XS selection t build-time. You may want to go that route, too, and there are legitimate reasons for that choice. On Tue, Oct 13, 2009 at 2:13 PM, Bill Ward b...@wards.net wrote: The Template Toolkit handles this with a command line option to Makefile.PL where you can build the toolkit with compiled code if the compiler is available. I don't think it has automatic detection as well, but it might. In any case you might want to consult with the Template Toolkit authors. Their mailing list is: http://mail.template-toolkit.org/mailman/listinfo/templates If you come up with a better solution, Template Toolkit might want to use it as well. On Tue, Oct 13, 2009 at 3:17 AM, O. STeffen BEYer ost...@gmail.com wrote: Dear Perl module authors, what would be the best way to detect whether a working C compiler is available at build time of a module (i.e., in Makefile.PL)? I would like to install a (faster) XS version of a module if that is the case, and a (slower) pure-Perl implementation if not. Remember that C compilers are not always available on all systems. Sometimes they cost heavy extra money, or sometimes you have to work with what's there on a customer's or provider's server (where frequently installing a C compiler is not an option due to company policies). Thank you! Best regards, Steffen Beyer http://www.engelschall.com/u/sb/download/ http://search.cpan.org/author/STBEY -- Check out my LEGO blog at http://www.brickpile.com/ View my photos at http://flickr.com/photos/billward/ Follow me at http://twitter.com/williamward
Re: How to best detect availability of C compiler in Makefile.PL?
Thanks a lot for all your valuable hints! I had a brief look at all of them. It seems that most of them are a bit overkill for what I want, or would mean some ugly messing with the symbol table through exporting imported identifiers. I like the straightforward approach that the user can choose at build time to install either implementation, and can always come back on his decision. Once the C version is installed, there is no reason to go back to the Perl version - but it's possible (e.g. for testing of code destined for a pure-Perl machine). Also, many of your suggestions need Perl modules to be installed on the target machine which do not exist on legacy Perl installations. Since Date::Calc is such a low-level basic module, it should be especially backward compatible, so that even people in old production environments (never fix what ain't broken) can upgrade my module and benefit from new functions, without having to install a load of other modules first - which their company policies would probably not permit. ExtUtils::CBuilder though seems a real winner, maybe I'll include this as an optional way to determine that the C compiler is really present and working, falling back to the method of scanning %Config and $ENV{PATH} if this module is not available. But first of all, I'll give it some more thought! Thanks again to you all! Cheers, Steffen