Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler does not recognize keywords in confess_at calls in XSP files #39

Closed
bwbeall opened this issue Nov 22, 2016 · 6 comments
Closed

Comments

@bwbeall
Copy link

bwbeall commented Nov 22, 2016

Version

1.31.6

Operating system type + version

Windows 10.0.14393 Pro x64
VS 2013 Version 12.0.40629.00 Update 5
NET Framework 4.6.01586

Behavior

I am building prusa3d/slic3r using the 1.31.6, and I am getting errors in statements that use the CONFESS macro. For example, in Config.xsp, the following code:

        if (GCodeConfig* config = dynamic_cast<GCodeConfig*>(THIS)) {
            RETVAL = config->get_extrusion_axis();
        } else {
           CONFESS("This StaticConfig object does not provide get_extrusion_axis()");  //395
        }

generates the following error messages:

Slic3r-master/xs/xsp/Config.xsp"(395) : error C2146: syntax error : missing ')' before identifier 'C'
Slic3r-master/xs/xsp/Config.xsp"(395) : error C2660: 'confess_at' : function does not take 1 arguments
Slic3r-master/xs/xsp/Config.xsp"(395) : error C2059: syntax error : ')'

Basically, the problem is the keywords FILE, LINE, and FUNCTION are not being recognized by the build process. When I replace the "CONFESS" statement with:

confess_at( FILE, LINE, FUNCTION, "This StaticConfig object does not provide get_extrusion_axis()");

I get the same errors, but when I replace it with:

confess_at( "FILE", 1, "FUNCTION", "This StaticConfig object does not provide get_extrusion_axis()");

there are no error messages generated. The same problem also occurs in GCode.xsp, TriangleMesh.xsp, Geometry.xsp, and Line.xsp. Oddly enough, this only happens on one of my two build computers (which are both substantially the same).

@bubnikv
Copy link
Collaborator

bubnikv commented Nov 22, 2016

This is a known problem of Perl XS/XSP compilers on Windows. See the following e-mail I sent to the XS/XSP maintainers:


I am trying to set up a development perl environment compiled from scratch with Visual Studio 2013 free C/C++ compiler. I stumbled over a following problem:

If the XS file contains an INCLUDE_COMMAND call, this line is later stored as a comment into the generated XS.c file in a form of #line NUMBER "filepath". Here the "filepath" will be the complete parameter of INCLUDE_COMMAND. If the parameter contains escaped quotes, this breaks the FILE substitution in the visual studio C++ compiler.

Here is an example of a #line inserted into XS.c, which the Visual Studio C++ has a problem with:

#line 112 "c:\\wperl64d\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t "D:/src-perl/Slic3r/xs/xsp/typemap.xspt" "D:/src-perl/Slic3r/xs/xsp/Print.xsp""

If I remove the quotes from the INCLUDE_COMMAND call, the resulting form is swallowed by the Visual Studio compiler without any problem.

#line 112 "c:\\wperl64d\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t D:/src-perl/Slic3r/xs/xsp/typemap.xspt D:/src-perl/Slic3r/xs/xsp/Print.xsp"

I see the following ways to fix this problem:

  1. The XS generator would remove the inner quotes from the #line comments when targeting the Visual Studio compiler

  2. The XS generator would save the intermediate file generated by the script in INCLUDE_COMMAND, and reference it in XS.c

Thanks for consideration,
Vojtech


How exactly does it fail? What error message does it produce?


What fails is the substitution of the FUNCTION macro, which is Microsoft's non-standard variant of the func macro defined by the C99 standard I believe. Visual Studio will fail to compile various asserts, which unfold the FUNCTION macro. I think what happens is the Visual Studio compiler somehow incorrectly interprets the quoting. The error message given by the compiler is confusing at least and it was quite hard to pinpoint it to the quotes in the #line.

@bwbeall
Copy link
Author

bwbeall commented Nov 22, 2016

So, I'll confess I know absolutely nothing about Perl or XS/XSP (it should be obvious), but it looks like the problem is with both of the string-related keywords (FILE and FUNCTION). I replaced the CONFESS macro with four lines, each of the first three has a single keyword (FILE, etc.) with literals for the other actual parameters; the fourth has literals for all four actual parameters. The two sets of error messages below are for the first and third lines (FILE and FUNCTION). The second and fourth lines (LINE) and no keywords both compiled successfully.

Here is the block of code from xs\xsp\Config.xsp, starting at line 43, with the CONFESS macro statement replaced with four statements to isolate the issue (near the bottom of the snippet):

%name{Slic3r::Config::Static} class StaticPrintConfig {
    static StaticPrintConfig* new_GCodeConfig()
        %code{% RETVAL = new GCodeConfig (); %};
    static StaticPrintConfig* new_PrintConfig()
        %code{% RETVAL = new PrintConfig (); %};
    static StaticPrintConfig* new_PrintObjectConfig()
        %code{% RETVAL = new PrintObjectConfig (); %};
    static StaticPrintConfig* new_PrintRegionConfig()
        %code{% RETVAL = new PrintRegionConfig (); %};
    static StaticPrintConfig* new_FullPrintConfig()
        %code{% RETVAL = new FullPrintConfig (); %};
    ~StaticPrintConfig();
    bool has(t_config_option_key opt_key);
    SV* as_hash()
        %code{% RETVAL = ConfigBase__as_hash(THIS); %};
    SV* get(t_config_option_key opt_key)
        %code{% RETVAL = ConfigBase__get(THIS, opt_key); %};
    SV* get_at(t_config_option_key opt_key, int i)
        %code{% RETVAL = ConfigBase__get_at(THIS, opt_key, i); %};
    bool set(t_config_option_key opt_key, SV* value)
        %code{% RETVAL = StaticConfig__set(THIS, opt_key, value); %};
    bool set_deserialize(t_config_option_key opt_key, SV* str)
        %code{% RETVAL = ConfigBase__set_deserialize(THIS, opt_key, str); %};
    void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false)
        %code{% ConfigBase__set_ifndef(THIS, opt_key, value, deserialize); %};
    std::string serialize(t_config_option_key opt_key);
    double get_abs_value(t_config_option_key opt_key);
    %name{get_abs_value_over}
        double get_abs_value(t_config_option_key opt_key, double ratio_over);
    void apply_static(StaticPrintConfig* other)
        %code{% THIS->apply(*other, true); %};
    void apply_dynamic(DynamicPrintConfig* other)
        %code{% THIS->apply(*other, true); %};
    %name{get_keys} std::vector<std::string> keys();
    std::string get_extrusion_axis()
        %code{%
            if (GCodeConfig* config = dynamic_cast<GCodeConfig*>(THIS)) {
                RETVAL = config->get_extrusion_axis();
            } else {
                //CONFESS("This StaticConfig object does not provide get_extrusion_axis()");
                confess_at(__FILE__,395,"get_extrusion_axis()","This StaticConfig object does not provide get_extrusion_axis()");
                confess_at("Config.xsp",__LINE__,"get_extrusion_axis()","This StaticConfig object does not provide get_extrusion_axis()");
                confess_at("Config.xsp",395,__FUNCTION__","This StaticConfig object does not provide get_extrusion_axis()");
                confess_at("Config.xsp",395,"get_extrusion_axis()","This StaticConfig object does not provide get_extrusion_axis()");
            }
        %};
    %name{setenv} void setenv_();
    double min_object_distance();
};

And here is the build output, first at point where the code generation/compile error occurs, then before it dies trying to generate the dll file.

...
buildtmp\XS.c(5561) : warning C4267: 'initializing' : conversion from 'size_t' to 'const unsigned int', possible loss of data
buildtmp\XS.c(6189) : warning C4800: 'UV' : forcing value to bool 'true' or 'false' (performance warning)
buildtmp\XS.c(6480) : warning C4267: 'initializing' : conversion from 'size_t' to 'const unsigned int', possible loss of data
c:\\wperl64r\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/typemap.xspt"  "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/Config.xsp"(396) : error C2146: syntax error : missing ')' before identifier 'C'
c:\\wperl64r\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/typemap.xspt"  "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/Config.xsp"(396) : error C2660: 'confess_at' : function does not take 1 arguments
c:\\wperl64r\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/typemap.xspt"  "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/Config.xsp"(396) : error C2059: syntax error : ')'
c:\\wperl64r\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/typemap.xspt"  "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/Config.xsp"(398) : error C2146: syntax error : missing ')' before identifier 'This'
c:\\wperl64r\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/typemap.xspt"  "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/Config.xsp"(398) : error C2660: 'confess_at' : function does not take 3 arguments
c:\\wperl64r\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/typemap.xspt"  "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/Config.xsp"(398) : error C2001: newline in constant
c:\\wperl64r\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/typemap.xspt"  "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/Config.xsp"(525) : warning C4267: 'argument' : conversion from 'size_t' to 'I32', possible loss of data
buildtmp\XS.c(7058) : warning C4244: 'initializing' : conversion from '__int64' to 'const unsigned int', possible loss of data
buildtmp\XS.c(7463) : warning C4244: 'initializing' : conversion from '__int64' to 'const unsigned int', possible loss of data
buildtmp\XS.c(7469) : warning C4244: '=' : conversion from 'UV' to 'unsigned int', possible loss of data

...

buildtmp\XS.c(41310) : warning C4267: 'initializing' : conversion from 'size_t' to 'const unsigned int', possible loss of data
buildtmp\XS.c(41449) : warning C4800: 'UV' : forcing value to bool 'true' or 'false' (performance warning)
buildtmp\XS.c(41491) : warning C4800: 'UV' : forcing value to bool 'true' or 'false' (performance warning)
c:\\wperl64r\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/typemap.xspt"  "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/PolylineCollection.xsp"(56) : warning C4267: '=' : conversion from 'size_t' to 'int', possible loss of data
c:\\wperl64r\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/typemap.xspt"  "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/PolylineCollection.xsp"(81) : warning C4018: '<' : signed/unsigned mismatch
c:\\wperl64r\\bin\\perl.exe -MExtUtils::XSpp::Cmd -e xspp -- -t "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/typemap.xspt"  "C:/Users/bwbeall/Downloads/Downloads/slic3r/Slic3r-master/xs/xsp/PolylineCollection.xsp"(117) : warning C4018: '<' : signed/unsigned mismatch
buildtmp\XS.c(42820) : warning C4244: '=' : conversion from 'double' to 'I32', possible loss of data
error building dll file from 'buildtmp\XS.c' at c:/wperl64r/lib/ExtUtils/CBuilder/Platform/Windows.pm line 129.
FAIL
! Installing ./xs failed. See C:\wperl64r\cpanm\work\1479823327.5884\build.log for details. Retry with --force to force install it.
The XS/C++ code failed to compile, aborting

So, I think for my kludge workaround, I'll replace the CONFESS macro with something like the second line 
confess_at("actual filename", __LINE__, "actual function", "actual message");

Suboptimal, but better than commenting out the whole line.

@bubnikv
Copy link
Collaborator

bubnikv commented Nov 22, 2016

You need to edit
youperl\site\lib\Module\Build\WithXSpp.pm
and remove some quotes. Just find the lines marked with "FIXME Vojtech" and replace them.
See the attached file.
WithXSpp-fixed.pm.txt

@bwbeall
Copy link
Author

bwbeall commented Nov 22, 2016

Agghhh.

That explains why it worked on one machine and not the other. I left that out of my instructions in yesterday's comments:

image

I'll go back and update my comments.

Thanks, and sorry for trouble.

@bwbeall
Copy link
Author

bwbeall commented Nov 22, 2016

BTW, how do you generate an exe, rather than a perl script for this?

@bubnikv
Copy link
Collaborator

bubnikv commented Nov 22, 2016

You are welcome. No problem, I am actually happy that someone was able to
follow the loooong procedure :-)

On Tue, Nov 22, 2016 at 4:22 PM, bwbeall notifications@github.com wrote:

Agghhh.

That explains why it worked on one machine and not the other. I left that
out of my instructions in yesterday's comments:

[image: image]
https://cloud.githubusercontent.com/assets/23196166/20529168/83f42f24-b08c-11e6-9404-8031df88d8cf.png

I'll go back and update my comments.

Thanks, and sorry for trouble.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#39 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AFj5I9T5hZ4qbFPA86DIGcPenV1YvDlgks5rAwi7gaJpZM4K5CIS
.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants