Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Building Parrot::Embed on Windows XP / Visual C++

11 views
Skip to first unread message

Ron Blaschke

unread,
Dec 22, 2006, 2:08:07 PM12/22/06
to perl6-i...@perl.org
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)

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

chromatic

unread,
Dec 22, 2006, 2:23:44 PM12/22/06
to perl6-i...@perl.org, r...@rblasch.org
On Friday 22 December 2006 11:08, Ron Blaschke wrote:

> 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

Ron Blaschke

unread,
Dec 22, 2006, 3:54:26 PM12/22/06
to chromatic, perl6-i...@perl.org
chromatic wrote:
> On Friday 22 December 2006 11:08, Ron Blaschke wrote:

>> 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

Chromatic

unread,
Dec 22, 2006, 7:02:57 PM12/22/06
to r...@rblasch.org, perl6-i...@perl.org
On Friday 22 December 2006 12:54, Ron Blaschke wrote:

> 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

Ron Blaschke

unread,
Dec 23, 2006, 2:32:13 PM12/23/06
to chromatic, perl6-i...@perl.org
chromatic wrote:
> On Friday 22 December 2006 12:54, Ron Blaschke wrote:
>> ----

>> -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);
>> ----
>> 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.

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

Chromatic

unread,
Dec 23, 2006, 4:12:49 PM12/23/06
to r...@rblasch.org, perl6-i...@perl.org
On Saturday 23 December 2006 11:32, Ron Blaschke wrote:

> 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

Ron Blaschke

unread,
Dec 27, 2006, 6:54:51 AM12/27/06
to chromatic, jerr...@gmail.com, perl6-i...@perl.org

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

0 new messages