What is the difference between -I. and -Ilib in Perl6? - metadata

I have a local distribution laid out as follows:
.
├── META6.json
└── lib
└── Foo.pm6
Both perl6 -I. -e 'use Foo;' and perl6 -Ilib -e 'use Foo;' compile and run, so which one should I use and why?

Another way of asking this question would be "What is the difference betweening -I $dir-with-meta6-file and -I $dir-without-meta6-file?". In this answer -I. will technically refer to -I $dir-with-meta6-file, and -Ilib will refer to -I $dir-without-meta6-file. Also note this covers use lib '.' and use lib 'lib'
The difference between -I. and -Ilib can be briefly be summarized:
-I. will look to the META6.json for what files/namespaces are provided and their version/api/auth
-Ilib provides all existing files and maps them to a predictable namespace (Foo/Bar.pm6 -> Foo::Bar) and will match any version/api/auth
Generally -Ilib gets used while developing, particularly when starting, because it is easier than manually adding/removing entries in the META6.json file. If you are writing a local application or something that is not intended to be installed this is mostly ok.
However! -I. should be preferred once a META6.json file has be created for the distribution. This can be slightly more work to maintain manually, but it has a few advantages:
It provides some basic assurance that it will install; a common problem I see is modules passing their tests but failing to actually install because precompilation on install only has access to the files listed in the META6.json file.
It allows mapping multiple namespaces to a single file (I'm not encouraging this).
You can have Perl .pm files next to Perl6 .pm6 files as a type of dual-language distribution since you can explicitly tell Perl6 which files to use. -Ilib must consider all .pm and .pm6 files as Perl6, and that is not compatible with this idea.

Related

Coq: manage LoadPath in project with subdirectories

I have a Coq project with its libraries organised into subdirectories, something like:
…/MyProj/Auxiliary/Aux.v
…/MyProj/Main/Main.v (imports Auxiliary/Aux.v)
When I compile the files, I expect to do so from working directory MyProj (via a makefile). But I also want to work on the files using Proof General/Coqtop, in which case the working directory is by default the directory in which the file lives.
But this means that the LoadPath is different between the two contexts, and so the logical path needed for the library import is different. How do I set up the coqc invocation, the LoadPath, and the import declarations so that they work in both contexts?
Each approach I have tried, something goes wrong. For instance, if I compile Aux.v by invoking
coqc -R "." "MyProj" Auxiliary/Aux.v
and import it in Main.v as
Require Import MyProj.Auxiliary.Aux.
then this works when I compile Main.v with
coqc -R "." "MyProj" Main/Main.v
but fails in Coqtop, with Error: Cannot find library MyProj.Auxiliary.Aux in loadpath. On the other hand, if before the Require Import I add
Add LoadPath ".." as MyProj.
then this works in Coqtop, but fails under coqc -R "." "MyProj" Main/Main.v, with
Error: The file […]/MyProj/Auxiliary/Aux.vo contains library
MyProj.Auxiliary.Aux and not library MyProj.MyProj.Auxiliary.Aux
I’m looking for a solution that’s robust for a library that’s shared with collaborators (and hopefully eventually with users), so in particular it can’t use absolute file paths. The best I have found for now is to add emacs local variables to set the LoadPath up when Proof General invokes Coqtop:
((coq-mode . ((coq-prog-args . ("-R" ".." "MyProj" "-emacs")))))
but this (a) seems a little hacky, and (b) only works for Proof General, not in Coqide or plain Coqtop. Is there a better solution?
Allow me to side-step your question by suggesting an alternative process, hinted at by Tiago.
Assuming that your project's tree looks like this:
MyProj/Auxiliary/Aux.v
MyProj/Main/Main.v
In MyProj, write a _CoqProject file listing all your Coq files
-R . ProjectName
Auxiliary/Aux.v
Main/Main.v
When you open one of these Coq files, emacs will look for the _CoqProject and do-the-right-thing (tm).
As shown by Tiago, coq_makefile will also give you a Makefile for free.
I know you explicitly asked for something that works across different platforms, but there's already a Proof-General-specific solution that is less hacky than the one you have. Proof General has a special variable called coq-load-path that you can set with local variables, much like you did for coq-prog-args. The advantage is that you don't have to worry about any other arguments that need to be passed to coqtop (such as -emacs in your example). Thus, your .dir-locals.el file could have a line like this:
((coq-mode . ((coq-load-path . ((".." "MyProj"))))))
Unfortunately, I am not aware of anything that works across platforms, although I'm pretty sure that something specific for CoqIDE must exist. If this is the case, maybe you could set up a script to keep these configuration files updated across different platforms?
If you use coq_makefile you can install the library in your system.
Without OPAM
To initialize your project:
coq_makefile -f _CoqProject -o Makefile
Share your library with other projects:
make install
With OPAM
Assuming you have OPAM installed, you can use coq-shell to help you take care of dependencies.
To setup your project:
coq_shell_url="https://raw.githubusercontent.com/gares/opam-coq-shell/master/src/opam-coq"
curl -s "${coq_shell_url}" | bash /dev/stdin init 8.4 # Install Coq and its dependencies
eval `opam config env --switch=coq-shell-8.4` # Setup the environment
coq_makefile -f _CoqProject -o Makefile # Generates the makefile
opam pin add coq:YOURLIBRARY . # Add your library to OPAM
When you update your library you should do:
opam upgrade coq:YOURLIBRARY
Here is an example of a project that uses the OPAM method:
https://bitbucket.org/cogumbreiro/aniceto-coq/src

MakeMaker update its list of files at `make` time

I'm working on a Perl module called Mite. It is a "compiler", of sorts. You write Perl classes using a Moose-like declarative OO syntax. Rather than doing all the work to put the class together every time it's executed, Mite does that work at build time. It generates an extra file containing the Perl code for your accessors and inheritance and whatnot.
This extra file is put into lib with the rest of your code and released with your project. As a result, the installing user does not need to install Mite and the code loads faster.
During development, the mite compiler is run when make or Build is run. So things like make test and ./Build test just work. This is accomplished by using special shims for MakeMaker or Module::Build.
This works fine for Module::Build, but ExtUtils::MakeMaker does not see the mite files. MakeMaker hard codes a list of what is in lib when Makefile.PL is run. The pm_to_lib step then fails to copy the generated files into blib where make test will see them.
How can I best work around this problem? I wish the process to remain transparent to the developer (once they've loaded the appropriate shim), and require no special dependencies for the installing user.
UPDATE: Here is a clearer example. Let's say you have a project like this.
Makefile.PL
lib/
Foo.pm
Bar.pm
Foo/
Thing.pm
t/
foo.t
bar.t
You run perl Makefile.PL and then make. The make step has been modified to generate an extra .mite.pm file for each .pm file. After the make step, what I want is this.
Makefile.PL
Makefile
lib/
Foo.pm
Foo.pm.mite.pm
Bar.pm
Bar.pm.mite.pm
Foo/
Thing.pm
Thing.pm.mite.pm
blib/
lib/
Foo.pm
Foo.pm.mite.pm
Bar.pm
Bar.pm.mite.pm
Foo/
Thing.pm
Thing.pm.mite.pm
t/
foo.t
bar.t
All the new files introduced into lib have been copied into blib/lib where they can be seen as part of make test. What I get instead is this.
Makefile.PL
Makefile
lib/
Foo.pm
Foo.pm.mite.pm
Bar.pm
Bar.pm.mite.pm
Foo/
Thing.pm
Thing.pm.mite.pm
blib/
lib/
Foo.pm
Bar.pm
Foo/
Thing.pm
t/
foo.t
bar.t
That is because the Makefile is generated by Makefile.PL with a hard coded list of what is in lib.
(This is particularly silly, I maintained MakeMaker for 10 years and failed to fix this.)
I wound up adding a new target and having pm_to_blib depend on it. The new target just moves all .pm files from lib/ to blib/lib/. The redundancy shouldn't matter.
I'm not happy with this solution, but it appears to work.
https://github.com/evalEmpire/Mite/commit/feff24e4d68e062a06a721591ff0d785c5dad80b

How can I install missing perl modules on an embedded system?

I'm running Linux on an embedded system, specifically Yocto Linux on a Cyclone V FPGA. I'm able to use Perl in its most basic form, but I'm unable to load any Perl modules. For example, when trying to use the GetOpt::Long module, I get the following error
root#socfpga_cyclone5:/mnt/sdcard# ./test.pl
Can't locate Getopt/Long.pm in #INC (#INC contains:
/etc/perl
/usr/lib/perl/site_perl/5.14.2/
/usr/lib/perl/site_perl/5.14.2
/usr/lib/perl/vendor_perl/5.14.2/
/usr/lib/perl/vendor_perl/5.14.2
/usr/lib/perl/5.14.2/
/usr/lib/perl/5.14.2
/usr/local/lib/site_perl
/usr/lib/perl/5.14.2
.) at ./test.pl line 3.
BEGIN failed--compilation aborted at ./test.pl line 3.
Does anybody know how I can go about installing these modules? Do the modules depend on hardware architecture at all? Is it reasonable to just copy and paste the .pm files somewhere from some source (and where would I be able to find and download these .pm files)?
I know your question is more than two years old, but it's a good question and I'm sad that nobody has answered it.
The perl ecosystem is very large, and the disk footprint of a full-featured perl installation is a problem on embedded systems. For that reason only a minimal system is installed when you add perl to your image. Other perl modules are available as bitbake packages.
Most of the time you can figure out what packages a recipe offers from the recipe, but the perl recipe is very complicated. The easiest way to find out what packages are built by the perl recipe is to build it (bitbake perl) and then look in the packages-split directory, which you will find in your bitbake work directory. For my system (cortex A8) that looks something like this:
$ ls -1 /poky/build/tmp/work/cortexa8hf-vfp-neon-poky-linux-gnueabi/perl/5.20.0-r1/packages-split
perl
perl-dbg
perl-dev
perl-doc
perl-lib
perl-lib.shlibdeps
perl-misc
perl-misc.shlibdeps
perl-module-anydbm-file
perl-module-app-cpan
perl-module-app-prove
perl-module-app-prove-state
(...)
If the module you want is listed, just add it to IMAGE_INSTALL like this:
IMAGE_INSTALL += "\
perl \
perl-module-base \
perl-module-bytes \
perl-module-data-dumper \
perl-module-digest-md5 \
perl-module-file-spec \
perl-module-file-spec-functions \
perl-module-findbin \
perl-module-getopt-long \
(...)"
If you want a module that isn't already being build, you will need to make your own recipe for it using the cpan class. See the examples in poky/meta/recipes-extended/perl and /poky/meta/recipes-lsb4/perl.
Editorializing, I've not been very happy with using perl on embedded systems. The biggest issue is the deferral of dependency resolution until runtime. It's too easy to mess this up and end up with Can't locate foobar.pm in #INC errors.
Have a look at this thread: https://lists.yoctoproject.org/pipermail/yocto/2013-July/015198.html
It sounds like perl modules have been packaged by whatever other thing needed first, but someone is working on making them available separately.
Some modules could be installed by just copying; others require a compiler or other build steps first. You are best off using whatever tools the yocto project provides.

Eclipse, QT and "C++ project": is it possible?

Need your help:
I want to use Eclipse CDT and QT without creating a "Qt gui project". Is it possible? How to include QT libraries to my C++ project, and how to call qmake/make to compile the program? This Similar question didn't help me(
I want to use 'C++ project' instead of 'QT Gui project' because there is an issue with external libraries indexing in the QT project (this problem)
Thank you a lot!
Nikolai.
We've done something similar using Qt with a vendor customized version of Eclipse (Momentics) and CDT. To get it to work, we ended up creating a generic makefile project in Eclipse with our own, hand generated Makefile.
The hand generated Makefile basically contained enough information to invoke QMake on the appropriate .pro file ("qt.pro") and then invoke the resulting Makefile ("qtmake.mk").
all: qtmake.mk
$(MAKE) -f qtmake.mk
qtmake.mk: qt.pro
qmake -r -o qtmake.mk qt.pro
clean: qtmake.mk
$(MAKE) -f qtmake.mk clean
install: qtmake.mk
$(MAKE) -f qtmake.mk install
Doing this is quite bothering, I suggest you don't do it. I've tried it only on small projects.
As far as I know you'll have to write a correct Makefile yourself (or setup CDT to create it) by including all the include paths you need for Qt headers. Then you'll have to link to all the Qt libraries your project is using.
If you make use of the Qt meta-object system you'll have to run the moc before compiling and linking. The moc generates C++ sources that you'll have to link to the other sources. If you're using GNU make, and I guess you are, it seems to be possible to automate the moc writing the correct instructions in the Makefile CDT will create. For detailed information read this: http://doc.qt.io/qt-5/moc.html#writing-make-rules-for-invoking.
By the way, isn't it possible for you to use Qt Creator?
This is very easy making use of Netbeans, since qt is integrated in the c++ projects.
But if you use Eclipse, as is my case, you could follow these two steps (for linux users):
Include the directories with the Qt headers, for example /usr/include/qt4/Qt.
Generate the moc files from the headers that contain Qt macros, such as Q_OBJECT. This can be done using the following command in the project directory before the build process:
find . -name ".h" | sed 's/(.)(/)(.*)(.h)/moc-qt4 -D & -o \1\2moc_\3.cpp/' | sh
where you have to define the you want. Just run it once, or use the following command before from the project directory:
find . -name "moc_*.cpp" -exec -rm -f {} \;
Build your project.
By the way, have you tried the qt plugging?
J.
Here is an improved variant of the jwernerny's makefile:
first: all
all clean distclean install uninstall: qtmake.mk
$(MAKE) -f qtmake.mk $#
qtmake.mk: *.pro
qmake -r -o qtmake.mk $<
.PHONY: first all clean distclean install uninstall
It should not to be edited when will be copied to another project, and actually the same rules was merged into one.

Can I build Perl modules with ExtUtils::MakeMaker-based build system "out of tree"?

Instead of adding or modifying files in the directory where the sources of a Perl module are unpacked, I would like to build everything in a separate directory. Is this easily achievable with a fairly standard Makefile.PL that uses ExtUtils::MakeMaker? (By easy, I mean something like one or a few command line parameters.) If no, does any of the other build systems support this?
Update / Reason: The Perl module is a binding to a library whose build system is autoconf/automake/libtool-based. The Perl module is shipped together with this library and calling make in the top directory eventually also builds the Perl library. I am interested in building the entire project in a separate build tree. At the moment I do something similar to what runrig suggested, only using symlinks. (cp -sru $(srcdir)/. $(builddir)/.). This has worked so far, but if there is a more elegant solution, I'd like to read about it.
MakeMaker already copies the sources and builds them in a separate directory (that's what blib/ is). You can control the build location with the INST_* set of arguments to WriteMakefile(). This example changes the location from blib/ to foo/.
INST_ARCHLIB => "foo/arch",
INST_LIB => "foo/lib",
INST_BIN => "foo/bin",
INST_SCRIPT => "foo/script",
INST_MAN1DIR => 'foo/man1',
INST_MAN3DIR => 'foo/man3',
In addition you have to tell MakeMaker to cleanup the new build directory.
clean => {
FILES => 'foo'
},
See "Determination of Perl Library and Installation Locations" in the ExtUtils::MakeMaker docs for more info.
cp -R Module-Directory-0.01 Module-Directory-0.01.copy
cd Module-Directory-0.01.copy
perl Makefile.PL
make
make test
...etc.
I ended up using symlinks:
The library to which the Perl module provides bindings uses an
autoconf/automake/libtool-based build system. Makefile.PL is
generated from Makefile.PL.in by configure. Makefile.PL
generates Makefile-pl (Makefile has already been taken by
autoconf/automake).
This is the relevant part of Makefile.am:
all: Makefile-pl src_deps
$(MAKE) -f Makefile-pl
Makefile-pl: Makefile.PL
perl Makefile.PL INSTALLDIRS=$(INSTALLDIRS) PREFIX=$(prefix)
I changed the second target to:
Makefile-pl: Makefile.PL
-[ $(srcdir) != $(builddir) ] && cp -rsu $(abs_srcdir)/. $(builddir)/.
perl Makefile.PL INSTALLDIRS=$(INSTALLDIRS) PREFIX=$(prefix)
This should work as long as building or installing the Perl module
does not result in any files being modified in-place.