Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^2: Do Pure Perl CPAN packages really need to use ExtUtils::Command::MM?

by ELISHEVA (Prior)
on Feb 17, 2011 at 20:18 UTC ( [id://888786]=note: print w/replies, xml ) Need Help??


in reply to Re: Do Pure Perl CPAN packages really need to use ExtUtils::Command::MM?
in thread Do Pure Perl CPAN packages really need to use ExtUtils::Command::MM?

Nonsense. MM doesn't care one bit....

I think we are misunderstanding each other. MM certainly isn't removing things from @INC or dying if it sees something it doesn't like. I am referring to the contents of @INC before any script calls use lib or any command line sets and exports PERL5LIB.

The contents of that @INC are hard coded to include the usual perl directories + the root of the project + blib/lib + blib/arch. MM generates the "test" target in the makefile using sub test in ExtUtils::MM_Unix (or whatever OS) which inherits from ExtUtils::MM_Any. The generated line in the make file is:

PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-MExtUtils::Command::MM" "-e" "test +_ha rness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES +)

ExtUtils::Command::MM::test_harness adds $(INST_LIB), i.e. blib/lib, and $(INST_ARCHLIB), i.e. blib/arch to @INC. It has no provision for adding anything more to @INC short of completely overriding sub test and generating my own custom test target. I call that hard coding.

I simply don't buy that it is a "good thing" to go around coding "use lib" statements in every single .t file. Module::Build does not make me do it. It gives me a way to make a one line change that automatically ensures that every test and every script knows where to find its support libraries without a single "use lib" statement. Do you really believe the world is a better place if I have to add a line to 16 files rather than one line to one file?

Just like you would have to do with any other script that wants to use uninstalled modules

Um no. Not just like I would do with any other script. To begin with, some of the modules I am thinking of distributing on CPAN get used in other projects that have nothing to do with CPAN (yes I own the IP). I have no need for that "use lib" statement when I run tests on those same modules for those other projects. I have no need of it when I let Module::Build build the project. I only have need of it, if I need it at all, to accommodate MM. I call that building to the tool. I also call that violation of separation of concerns.

I imagine that 100% of testers try to use Makefile.PL, not 3%. They just might not try it first.

I am not proposing doing away with Makefile.PL. Option B keeps Makefile.PL but simply implements the targets with Module::Build rather than ExtUtil::Command::MM. You can still use Makefile.PL to generate a makefile and have it work perfectly if you feel more comfortable that way.

You might well be right that they tried Makefile.PL first. However, in the final analysis, whether they tried it first or not is immaterial. So long as Module::Build is available to try at all, it means that a makefile backed by Module::Build will work.

Replies are listed 'Best First'.
Re^3: Do Pure Perl CPAN packages really need to use ExtUtils::Command::MM?
by Eliya (Vicar) on Feb 17, 2011 at 21:55 UTC
    ...I am referring to the contents of @INC before any script calls use lib or any command line sets and exports PERL5LIB.

    I'm not saying this is the recommended way to do it, but technically, the following should work:

    Set PERL5LIB in the Makefile

    export PERL5LIB = ...path/to/lib

    As any command being run for the "test" target (or any other target) is a subprocess of make, it will inherit the environment variable, so the lib dir is being added to @INC for all tests.

    What remains to be solved is how to get MakeMaker to put the above line in the generated Makefile. A quick test shows that this can be achieved by overriding the routine post_initialize, which is responsible for creating a (normally empty) section at the beginning of the Makefile.  I.e., add a MY::post_initialize routine to your Makefile.PL:

    use ExtUtils::MakeMaker; sub MY::post_initialize { return "export PERL5LIB = ...path/to/lib"; } WriteMakefile( ... );

    This generates a section in the Makefile

    # --- MakeMaker post_initialize section: export PERL5LIB = ...path/to/lib

    which causes make to set PERL5LIB in its environment.

      I want to ++ this a thousand times tonight. This worked! I totally missed the "MY::post_initialize" when I was reading the docs and studying the source code yesterday.

      I had to modify it slightly so I didn't clobber the user's settings. Some people install CPAN software into their home dir and may be using PERL5LIB to add those to their module search path.

      use File::Spec; use Config; sub MY::post_initialize { my $sInc = File::Spec->rel2abs('inc', $ENV{PWD}); my $sSep = $Config{path_sep}; my $PERL5LIB=$ENV{PERL5LIB}; return "PERL5LIB := $PERL5LIB$sSep$sInc"; }

      Update: After grepping through the code one more time I found where this is documented:ExtUtils::MM::Unix. I do remember reading it yesterday, but when I read the documentation I didn't connect the dots:

      Returns an empty string per default. Used in Makefile.PLs to add some chunk of text to the Makefile after the object is initialized.

      The object, what object? Thanks once again.

      Update: added comment about portable way to append paths to PERL5LIB

      Update: updated with resolution portability issue

Re^3: Do Pure Perl CPAN packages really need to use ExtUtils::Command::MM?
by ikegami (Patriarch) on Feb 17, 2011 at 20:57 UTC

    ExtUtils::Command::MM::test_harness adds $(INST_LIB), i.e. blib/lib, and $(INST_ARCHLIB), i.e. blib/arch to @INC. It has no provision for adding anything more to @INC

    Exactly. Your claim that there's something special about the project root is completely false.

    I simply don't buy that it is a "good thing" to go around coding "use lib" statements in every single .t file.

    It's a necessary thing, not just in .t, but in all scripts that use uninstalled modules. If you don't, Perl won't find them. If the module isn't somewhere where Perl would normally look (e.g. the directory in which the script resides), you need to tell Perl where it is.

    No idea why you bring up CPAN and legal protections.

    First, it means that I have to go into every file I want to ship and edit it to have that line.

    No, just the scripts.

    Secondly, these support libraries are used in a lot of different projects

    Straw man. If Perl can find your libraries, they don't need to tell Perl where to find your libraries.

    Secondly, if you have a module that used by multiple projects, it's silly to copy it into each project and adjusting @INC to find that copy. Install the module.

    I have no need of it when I let Module::Build build the project.

    So you're proudly claiming that one needs to use a giant harness to get your test script to work properly, ignoring that it fails the rest of the time.

    I am not proposing doing away with Makefile.PL.

    I didn't even address your proposal. I just corrected the false claim that only 3% of testers try to run Makefile.PL.

    To address the proposal: It's a lot of work and you claim introduces problems, while you can get the desired effect by simply adding inc/ to the harness command. And your test script still won't run outside the harness.

    Before you reply that you don't expect your test scripts outside of Module::Build, realise there's no problem if that's true.

      our claim that there's something special about the project root is completely false.

      Huh? Project root is in there too. It just isn't added by the test target because it is already there. Its specialness comes from the fact that it is the only path within the project area that (a) is in the hardcoded @INC and (b) does not include files that will be installed at runtime. Thus it is the only directory within @INC that can be used for libraries that are needed by tests/setup but should not be installed to INSTALLDIR after all tests pass. If I want to avoid splattering "use lib" all over the place I have to put such files in root. Nothing I have said is remotely false.

      So you're proudly claiming that one needs to use a giant harness

      Huh? Who said anything about a giant harness? Because I can add one line to Build.PL and Module::Build generates a ./Build file that inserts a path in @INC, that counts as a giant harness?

      My automated build process manages to configure itself without splattering "use lib" all over the place as well. Automated build processes are evil giant harnesses?

      In my day to day work area code is not divided into separate source trees for each project, nor for each packaging tool. There is a single source tree for everything. "use lib" is completely irrelevant and unnecessary. If I want to run a test I place myself at the source of the tree and run "prove". If I want to run a script, I place myself at the source of the tree and type the script name, "Foo/Baz.pl". Is prove a giant evil harness? Is standing at the root of the source tree?

      The only thing I've claimed is that splattering "use lib" or Find::Bin + use lib all over my scripts reflects the needs of a specific run environment - that created by ExtUtils::MakeMaker. It is completely unnecessary if those tests are run in the environment created by Module::Build. "use lib" is completely unnecessary in nearly any other environment I run my test scripts. Thus I conclude that putting that code in every script violates separation of concerns and constitutes programming to the tool. You have not yet addressed those two issues.

      I've used lots of different build tools and installers over the years and MM strikes me as the only one that expected me to modify my source code to accommodate it.

      ignoring that it fails the rest of the time.

      When you equate difficulties with MM to "the rest of the time", I can't help wondering whether you've decided that the only "real" tool is MM and any other successful run of my tests is irrelevant. In every other environment, including a makefile backed by Module::Build they run fine without splattering "use lib" all over my scripts. They'll run fine under ExtUtils::Command::MM if there is a portable way to put "projectroot/inc" into @INC as well.

      Update: Removed some stuff that was really besides the point.

        I didn't mean to start reading this now, since I got to go, but the first sentence caught my eye.

        Huh? Project root is in there too.

        My test shows differently. That's apparently not something you can rely on.

        Huh? Who said anything about a giant harness? Because I can add one line to Build.PL and Module::Build generates a ./Build file that inserts a path in @INC, that counts as a giant harness?

        I did. Because having to use bash -c'cd .. ; ./Build test' to run a single test is not right. It runs all the tests instead of the one you want, and I think it doesn't even give the full test output.

        Automated build processes are evil giant harnesses?

        I never said evil. Just inappropriate for some tasks.

        I've used lots of different build tools and installers over the years and MM strikes me as the only one that expected me to modify my source code to accommodate it.

        It doesn't expect anything of the kind. If your script wasn't buggy in the first place, you wouldn't have to modify it.

        In short, there are many ways to do things and many different environments that scripts run in. One should not assume that everyone who does something different than your way or MM's way is doing something evil and bad (technicaly speaking) the way you just did with me.

        That's my point. You're assuming that it's M::B vs M::M, but it's not. The solution to your script being broken even in a M::B distro isn't to change M::M.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://888786]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2024-04-18 19:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found