$ ./Build test
t\interp....ok 1/31Parrot VM: Can't stat no file here, code 2.
error:imcc:syntax error, unexpected IDENTIFIER
in file 'EVAL_2' line 1
t\interp....ok
All tests successful.
Files=1, Tests=31, 0 wallclock secs ( 0.00 cusr + 0.00 csys =
0.00 CPU)
There are three steps necessary (four using VC8).
1) Two additional functions need to be exported.
Parrot_register_pmc
Parrot_unregister_pmc
2) Change the compiler and linker flags.
3) Add the path to parrot.dll to Path, so it can be found during (test)
execution.
Step 2 is the hard part, and I'd like to ask for some advice. The flags
seem to come from F<parrot.pc>, generated from the input file
F<config/gen/makefiles/parrot.pc.in>. The relevant entries are:
Libs: -L${libdir} -lparrot
Cflags: -I${includedir}
The C<Cflags> seem to be added correctly in Module::Build (version
0.2805) to the C<extra_compiler_flags>, but they don't get passed to the
compiler. I needed to change C<incpath> for this. This seems to be an
issue with Module::Build, but I need to double check this.
Second, C<Libs> is not right for Visual C++ (but added to
C<extra_linker_flags> and passed to the linker.)
F<config/gen/makefiles/parrot.pc.in> says:
Libs: -L${libdir} -lparrot @icu_shared@ @libs@
Visual C++ needs:
${libdir}/libparrot.lib @icu_shared@ @libs@
or
/LIBPATH:${libdir} libparrot.lib @icu_shared@ @libs@
Any recommended way to get there?
Thanks,
Ron
> I have managed to build Parrot::Embed on Windows/VC8, and judging from
> the test output it works. There are two warnings, but I guess those are
> no problem?
>
> $ ./Build test
> t\interp....ok 1/31Parrot VM: Can't stat no file here, code 2.
> error:imcc:syntax error, unexpected IDENTIFIER
> in file 'EVAL_2' line 1
> t\interp....ok
> All tests successful.
> Files=1, Tests=31, 0 wallclock secs ( 0.00 cusr + 0.00 csys =
> 0.00 CPU)
Right. Those should be trappable from the embedding interface, but they
aren't.
> There are three steps necessary (four using VC8).
>
> 1) Two additional functions need to be exported.
> Parrot_register_pmc
> Parrot_unregister_pmc
In some .def file somewhere, or marked somehow in the source code?
> 2) Change the compiler and linker flags.
>
> 3) Add the path to parrot.dll to Path, so it can be found during (test)
> execution.
That's tough on all platforms. Is it a simple case of adding ../../blib/lib
to $ENV{PATH} before executing the tests?
> Step 2 is the hard part, and I'd like to ask for some advice. The flags
> seem to come from F<parrot.pc>, generated from the input file
> F<config/gen/makefiles/parrot.pc.in>. The relevant entries are:
>
> Libs: -L${libdir} -lparrot
> Cflags: -I${includedir}
>
> The C<Cflags> seem to be added correctly in Module::Build (version
> 0.2805) to the C<extra_compiler_flags>, but they don't get passed to the
> compiler. I needed to change C<incpath> for this. This seems to be an
> issue with Module::Build, but I need to double check this.
Is C<incpath> a separate M::B option for Win32?
> Second, C<Libs> is not right for Visual C++ (but added to
> C<extra_linker_flags> and passed to the linker.)
>
> F<config/gen/makefiles/parrot.pc.in> says:
>
> Libs: -L${libdir} -lparrot @icu_shared@ @libs@
>
> Visual C++ needs:
>
> ${libdir}/libparrot.lib @icu_shared@ @libs@
> or
> /LIBPATH:${libdir} libparrot.lib @icu_shared@ @libs@
>
> Any recommended way to get there?
Does pkg-config work on Windows? If not, modifying that file is rather moot,
and Parrot::Embed can work another way. Another option is to use
Parrot::Config, if that'll be available and installed. That might be a
better option.
I'm open to ideas.
-- c
>> There are three steps necessary (four using VC8).
>>
>> 1) Two additional functions need to be exported.
>> Parrot_register_pmc
>> Parrot_unregister_pmc
>
> In some .def file somewhere, or marked somehow in the source code?
The necessary change is:
----
$ svn diff include/parrot/extend.h
Index: include/parrot/extend.h
===================================================================
--- include/parrot/extend.h (revision 16218)
+++ include/parrot/extend.h (working copy)
@@ -121,8 +121,8 @@
Parrot_Language Parrot_find_language(Parrot_INTERP, char*);
-void Parrot_register_pmc(Parrot_INTERP, Parrot_PMC);
-void Parrot_unregister_pmc(Parrot_INTERP, Parrot_PMC);
+PARROT_API void Parrot_register_pmc(Parrot_INTERP, Parrot_PMC);
+PARROT_API void Parrot_unregister_pmc(Parrot_INTERP, Parrot_PMC);
Parrot_PMC Parrot_get_dod_registry(Parrot_INTERP);
----
I thought I'd collect everything necessary together and submit a single
patch.
>> 2) Change the compiler and linker flags.
>>
>> 3) Add the path to parrot.dll to Path, so it can be found during (test)
>> execution.
>
> That's tough on all platforms. Is it a simple case of adding ../../blib/lib
> to $ENV{PATH} before executing the tests?
Yes. ${libdir} points to F<../../blib/lib>, but on Windows the DLL is
put into the root directory, like F<miniparrot.exe> or F<parrot.exe>.
Not sure about other platforms. So F<../..> would do for Windows.
>> Step 2 is the hard part, and I'd like to ask for some advice. The flags
>> seem to come from F<parrot.pc>, generated from the input file
>> F<config/gen/makefiles/parrot.pc.in>. The relevant entries are:
>>
>> Libs: -L${libdir} -lparrot
>> Cflags: -I${includedir}
>>
>> The C<Cflags> seem to be added correctly in Module::Build (version
>> 0.2805) to the C<extra_compiler_flags>, but they don't get passed to the
>> compiler. I needed to change C<incpath> for this. This seems to be an
>> issue with Module::Build, but I need to double check this.
>
> Is C<incpath> a separate M::B option for Win32?
I have to admit I just hacked F<_build/build_params> to get P::E
compiled. I'm not sure where C<incpath> is coming from. On my box it says:
'incpath' => '\\include'
I'll have to keep searching for this.
C<extra_compiler_flags> is:
'extra_compiler_flags' => [
'-I/usr/local/include',
'-I..\\..\\include'
],
But I don't see them during the call to the compiler.
>
>> Second, C<Libs> is not right for Visual C++ (but added to
>> C<extra_linker_flags> and passed to the linker.)
>>
>> F<config/gen/makefiles/parrot.pc.in> says:
>>
>> Libs: -L${libdir} -lparrot @icu_shared@ @libs@
>>
>> Visual C++ needs:
>>
>> ${libdir}/libparrot.lib @icu_shared@ @libs@
>> or
>> /LIBPATH:${libdir} libparrot.lib @icu_shared@ @libs@
>>
>> Any recommended way to get there?
>
>
> Does pkg-config work on Windows? If not, modifying that file is rather moot,
> and Parrot::Embed can work another way. Another option is to use
> Parrot::Config, if that'll be available and installed. That might be a
> better option.
>
> I'm open to ideas.
Sorry, no pkg-config here. Not sure if there are other toolkits, like
MinGW or Cygwin, that are providing it. I'm not a Linux/UNIX regular,
is F<parrot.pc> used by this tool? The file is parsed directly by
P::E's Build.PL, so I thought it's just a random format.
Just thinking loud here, but even if there isn't a pkg-config on Windows
we could reuse the file. C<parrot.pc> is generated by Configure using
the template F<config/gen/makefiles/parrot.pc.in>. One way I can see
would be to put the parrot library options into a variable, like this:
Libs: @libparrot_shared@ @icu_shared@ @libs@
with @libparrot_shared@ == "-L${libdir} -lparrot" on GCC (not sure where
else, too)
and @libparrot_shared@ == "${libdir}/libparrot.lib" on VC.
Another way would be to template all of C<parrot.pc.in>, by adding
C<vc_parrot.pc.in>, and select the right template during source generation.
In my opinion Parrot::Config is probably not the best way to handle
this. The paths are relative and not expanded, for example:
'cc_inc' => '-I./include',
'libparrot' => '$(LIBPARROT_SHARED)',
'libparrot_ldflags' => 'libparrot$(A)',
'libparrot_shared' => 'libparrot$(SHARE_EXT)',
I guess P::C is more for introspection how Parrot was built, not how to
build an extension.
Maybe it would be enough to come up with some platform specific search
code for Windows in P::C's Build.PL. After all, everything we need is
the library and the headers. I'm wondering how other Perl modules
handle this...
Any thoughts are greatly appreciated,
Ron
> The necessary change is:
>
> ----
> $ svn diff include/parrot/extend.h
> Index: include/parrot/extend.h
> ===================================================================
> --- include/parrot/extend.h (revision 16218)
> +++ include/parrot/extend.h (working copy)
> @@ -121,8 +121,8 @@
>
> Parrot_Language Parrot_find_language(Parrot_INTERP, char*);
>
> -void Parrot_register_pmc(Parrot_INTERP, Parrot_PMC);
> -void Parrot_unregister_pmc(Parrot_INTERP, Parrot_PMC);
> +PARROT_API void Parrot_register_pmc(Parrot_INTERP, Parrot_PMC);
> +PARROT_API void Parrot_unregister_pmc(Parrot_INTERP, Parrot_PMC);
> Parrot_PMC Parrot_get_dod_registry(Parrot_INTERP);
> ----
>
> I thought I'd collect everything necessary together and submit a single
> patch.
That patch works for me, but if you want to hold off it's fine. Anything that
embeds Parrot needs to use those APIs anyway, so it's not a P::E specific
fix.
> > That's tough on all platforms. Is it a simple case of adding
> > ../../blib/lib to $ENV{PATH} before executing the tests?
>
> Yes. ${libdir} points to F<../../blib/lib>, but on Windows the DLL is
> put into the root directory, like F<miniparrot.exe> or F<parrot.exe>.
> Not sure about other platforms. So F<../..> would do for Windows.
Alright. Unix needs a similar fix, so I think I'll have to find some way to
set that for C<./Build test>, so when it launches child processes, they have
the correct environment variables to find the shared library. (I think
C<LD_RUN_PATH> works fairly well for the Unixes I know.)
> > Is C<incpath> a separate M::B option for Win32?
>
> I have to admit I just hacked F<_build/build_params> to get P::E
> compiled. I'm not sure where C<incpath> is coming from. On my box it
> says:
>
> 'incpath' => '\\include'
>
> I'll have to keep searching for this.
Right. That's the point where Jerry and I had trouble; we couldn't quite
figure out the right compiler flags for Win32.
> C<extra_compiler_flags> is:
>
> 'extra_compiler_flags' => [
> '-I/usr/local/include',
> '-I..\\..\\include'
> ],
>
> But I don't see them during the call to the compiler.
It may be somewhere in the guts of ExtUtils::CBuilder.
> Sorry, no pkg-config here. Not sure if there are other toolkits, like
> MinGW or Cygwin, that are providing it. I'm not a Linux/UNIX regular,
> is F<parrot.pc> used by this tool? The file is parsed directly by
> P::E's Build.PL, so I thought it's just a random format.
It's a Unix tool that helps linking against installed libraries. F<Build.PL>
parses it because it's probably close to correct.
> Just thinking loud here, but even if there isn't a pkg-config on Windows
> we could reuse the file. C<parrot.pc> is generated by Configure using
> the template F<config/gen/makefiles/parrot.pc.in>. One way I can see
> would be to put the parrot library options into a variable, like this:
>
> Libs: @libparrot_shared@ @icu_shared@ @libs@
>
> with @libparrot_shared@ == "-L${libdir} -lparrot" on GCC (not sure where
> else, too)
> and @libparrot_shared@ == "${libdir}/libparrot.lib" on VC.
>
> Another way would be to template all of C<parrot.pc.in>, by adding
> C<vc_parrot.pc.in>, and select the right template during source generation.
Unless and until there's a pkg-config for Windows, it's probably not worth
doing this, as nothing else will use it.
> In my opinion Parrot::Config is probably not the best way to handle
> this. The paths are relative and not expanded, for example:
>
> 'cc_inc' => '-I./include',
> 'libparrot' => '$(LIBPARROT_SHARED)',
> 'libparrot_ldflags' => 'libparrot$(A)',
> 'libparrot_shared' => 'libparrot$(SHARE_EXT)',
>
> I guess P::C is more for introspection how Parrot was built, not how to
> build an extension.
Fair enough.
> Maybe it would be enough to come up with some platform specific search
> code for Windows in P::C's Build.PL. After all, everything we need is
> the library and the headers. I'm wondering how other Perl modules
> handle this...
There are really only two things that P::E needs in two places:
- the header and library path for compiling and linking
- the library path for running
This is generally only tricky when building in-tree, as there's no guarantee
of an installed Parrot. Outside of the tree, there's no point in continuing
if the headers aren't present; I'm not going to scan the attached mount
points to try to find a likely target.
-- c
It would be great if you could make the change right away. I thought it
was just too small of a change to submit an official patch.
>> Sorry, no pkg-config here. Not sure if there are other toolkits, like
>> MinGW or Cygwin, that are providing it. I'm not a Linux/UNIX regular,
>> is F<parrot.pc> used by this tool? The file is parsed directly by
>> P::E's Build.PL, so I thought it's just a random format.
>
> It's a Unix tool that helps linking against installed libraries. F<Build.PL>
> parses it because it's probably close to correct.
I see.
>> Maybe it would be enough to come up with some platform specific search
>> code for Windows in P::C's Build.PL. After all, everything we need is
>> the library and the headers. I'm wondering how other Perl modules
>> handle this...
>
> There are really only two things that P::E needs in two places:
>
> - the header and library path for compiling and linking
> - the library path for running
>
> This is generally only tricky when building in-tree, as there's no guarantee
> of an installed Parrot. Outside of the tree, there's no point in continuing
> if the headers aren't present; I'm not going to scan the attached mount
> points to try to find a likely target.
Right. If in-tree, would it make sense to just ignore parrot.pc and
assume the file locations? Maybe under some additional condition - e.g.
Windows / Visual C++, not to disrupt the current scheme where it's working?
Thanks for your help,
Ron
> It would be great if you could make the change right away. I thought it
> was just too small of a change to submit an official patch.
Thanks, applied as of r16229.
> > This is generally only tricky when building in-tree, as there's no
> > guarantee of an installed Parrot. Outside of the tree, there's no point
> > in continuing if the headers aren't present; I'm not going to scan the
> > attached mount points to try to find a likely target.
> Right. If in-tree, would it make sense to just ignore parrot.pc and
> assume the file locations? Maybe under some additional condition - e.g.
> Windows / Visual C++, not to disrupt the current scheme where it's working?
I considered that briefly for all platforms at the start, but I figured I
wanted to allow people to install Parrot::Embed to run against an uninstalled
Parrot. Perhaps no one will want to do that.
-- c
I'm not using P::E myself, but like to smoke it and make it work for
others. So, for me it would be good if I can keep everything in the
smoke chamber, but that's not too important.
As you said, P::E needs the header and library path for compiling and
linking, and the library path for running. I'd need some help where to
look for them / get them from. This is mostly about others, as I have
no second thought digging as deep into the guts as necessary to make it
work for me. That's probably why I'm not quite sure what to do here. ;-)
Ron