gvr has asked for the wisdom of the Perl Monks concerning the following question:

I am getting the following error during compilation for Encode::Detect on windows.
Microsoft (R) Program Maintenance Utility Version 6.00.8168.0 Copyright (C) Microsoft Corp 1988-1998. All rights reserved. C:\Perl\bin\perl.exe Build --makefile_env_macros 1 Copying Detector.xs -> lib\Encode\Detect\Detector.xs lib\Encode\Detect\Detector.xs -> lib\Encode\Detect\Detector.c Use of uninitialized value $ExtUtils::ParseXS::report_args in concaten +ation (.) or string at C:/Perl/lib/ExtUtils/ParseXS.pm line 515, <GEN +8> line Generating script 'lib\Encode\Detect\Detector.ccs' cl -nologo -c @"lib\Encode\Detect\Detector.ccs" -Fo"lib\Encode\Detect\ +Detector.obj" "lib\Encode\Detect\Detector.c" Detector.c lib\Encode\Detect\Detector.xs(37) : error C2059: syntax error : 'strin +g' src\nsUniversalDetector.h(41) : error C2061: syntax error : identifier + 'nsCharSetProber' src\nsUniversalDetector.h(41) : error C2059: syntax error : ';' src\nsUniversalDetector.h(51) : error C2061: syntax error : identifier + 'nsUniversalDetector' src\nsUniversalDetector.h(51) : error C2059: syntax error : ';' src\nsUniversalDetector.h(51) : error C2449: found '{' at file scope ( +missing function header?) src\nsUniversalDetector.h(72) : error C2059: syntax error : '}' lib\Encode\Detect\Detector.c(82) : error C2143: syntax error : missing + ')' before '*' lib\Encode\Detect\Detector.c(82) : error C2143: syntax error : missing + '{' before '*' lib\Encode\Detect\Detector.c(82) : error C2143: syntax error : missing + ';' before '*' lib\Encode\Detect\Detector.c(82) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(83) : error C2143: syntax error : missing + ')' before '*' lib\Encode\Detect\Detector.c(83) : error C2143: syntax error : missing + '{' before '*' lib\Encode\Detect\Detector.c(83) : error C2143: syntax error : missing + ';' before '*' lib\Encode\Detect\Detector.c(83) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(84) : error C2054: expected '(' to follow + 'cv' lib\Encode\Detect\Detector.c(106) : error C2143: syntax error : missin +g ')' before '*' lib\Encode\Detect\Detector.c(106) : error C2143: syntax error : missin +g '{' before '*' lib\Encode\Detect\Detector.c(106) : error C2143: syntax error : missin +g ';' before '*' lib\Encode\Detect\Detector.c(106) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(107) : error C2143: syntax error : missin +g ')' before '*' lib\Encode\Detect\Detector.c(107) : error C2143: syntax error : missin +g '{' before '*' lib\Encode\Detect\Detector.c(107) : error C2143: syntax error : missin +g ';' before '*' lib\Encode\Detect\Detector.c(107) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(108) : error C2054: expected '(' to follo +w 'cv' lib\Encode\Detect\Detector.c(133) : error C2143: syntax error : missin +g ')' before '*' lib\Encode\Detect\Detector.c(133) : error C2143: syntax error : missin +g '{' before '*' lib\Encode\Detect\Detector.c(133) : error C2143: syntax error : missin +g ';' before '*' lib\Encode\Detect\Detector.c(133) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(134) : error C2143: syntax error : missin +g ')' before '*' lib\Encode\Detect\Detector.c(134) : error C2143: syntax error : missin +g '{' before '*' lib\Encode\Detect\Detector.c(134) : error C2143: syntax error : missin +g ';' before '*' lib\Encode\Detect\Detector.c(134) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(135) : error C2054: expected '(' to follo +w 'cv' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +')' before '*' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +'{' before '*' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +';' before '*' lib\Encode\Detect\Detector.c(6) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(7) : error C2143: syntax error : missing +')' before '*' lib\Encode\Detect\Detector.c(7) : error C2143: syntax error : missing +'{' before '*' lib\Encode\Detect\Detector.c(7) : error C2143: syntax error : missing +';' before '*' lib\Encode\Detect\Detector.c(7) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(8) : error C2054: expected '(' to follow +'cv' lib\Encode\Detect\Detector.c(5) : error C2143: syntax error : missing +')' before '*' lib\Encode\Detect\Detector.c(5) : error C2143: syntax error : missing +'{' before '*' lib\Encode\Detect\Detector.c(5) : error C2143: syntax error : missing +';' before '*' lib\Encode\Detect\Detector.c(5) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +')' before '*' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +'{' before '*' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +';' before '*' lib\Encode\Detect\Detector.c(6) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(7) : error C2054: expected '(' to follow +'cv' lib\Encode\Detect\Detector.c(5) : error C2143: syntax error : missing +')' before '*' lib\Encode\Detect\Detector.c(5) : error C2143: syntax error : missing +'{' before '*' lib\Encode\Detect\Detector.c(5) : error C2143: syntax error : missing +';' before '*' lib\Encode\Detect\Detector.c(5) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +')' before '*' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +'{' before '*' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +';' before '*' lib\Encode\Detect\Detector.c(6) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(7) : error C2054: expected '(' to follow +'cv' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +')' before '*' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +'{' before '*' lib\Encode\Detect\Detector.c(6) : error C2143: syntax error : missing +';' before '*' lib\Encode\Detect\Detector.c(6) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(7) : error C2143: syntax error : missing +')' before '*' lib\Encode\Detect\Detector.c(7) : error C2143: syntax error : missing +'{' before '*' lib\Encode\Detect\Detector.c(7) : error C2143: syntax error : missing +';' before '*' lib\Encode\Detect\Detector.c(7) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(8) : error C2054: expected '(' to follow +'cv' lib\Encode\Detect\Detector.c(8) : error C2143: syntax error : missing +')' before '*' lib\Encode\Detect\Detector.c(8) : error C2143: syntax error : missing +'{' before '*' lib\Encode\Detect\Detector.c(8) : error C2143: syntax error : missing +';' before '*' lib\Encode\Detect\Detector.c(8) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(9) : error C2143: syntax error : missing +')' before '*' lib\Encode\Detect\Detector.c(9) : error C2143: syntax error : missing +'{' before '*' lib\Encode\Detect\Detector.c(9) : error C2143: syntax error : missing +';' before '*' lib\Encode\Detect\Detector.c(9) : error C2059: syntax error : ')' lib\Encode\Detect\Detector.c(10) : error C2054: expected '(' to follow + 'cv' error building dll file from 'lib\Encode\Detect\Detector.c' at C:/Perl +/lib/ExtUtils/CBuilder/Platform/Windows.pm line 143. NMAKE : fatal error U1077: 'C:\Perl\bin\perl.exe' : return code '0x2' Stop.
I remember reading somewhere that Encode::Detect does not work on Windows. Any workarounds? Thanks

Replies are listed 'Best First'.
Re: Cannot compile Encode::Detect on Windows
by BrowserUk (Patriarch) on Apr 16, 2009 at 18:46 UTC

    The problem is that the file: detector.xs is being compiled as C, but it contains C++ extensions:

    extern "C" {

    The file compiles clean (with a couple of trivial warnings), if you add option -TP to cause the compiler to treat the file as C++.

    Unfortunately, as with all these build mechanisms, the process is so stupidly convoluted that working out how to add a simple compiler option is your typical OO maze of dark, twisty packages.

    The way I tested it was:

    1. start the compile (using command nmake) at the command line and the immediately pause it using ^S.
    2. Switch to another session, and make a copy of the file under a different name: Encode-Detect-1.01\lib\Encode\Detect\Detector.ccs.

      This is a compiler "options response file" that is generated automatically, but then deleted.

    3. Switch back to the first session and hit any key allowing the compile to continue to failure.
    4. Edit the file you saved and add -TP as a new last line.
    5. Rename the file back to Encode-Detect-1.01\lib\Encode\Detect\Detector.ccs
    6. Switch back to the first session, and C&P the last compiler command issued by the nmake. It should look something like this:
      C:\Perl64\packages\Encode-Detect-1.01>cl -nologo -c @"lib\Encode\Detec +t\Detector.ccs" -Fo"lib\Encode\Detect\Detector.obj" "lib\Encode\Detec +t\Detector.c" Detector.c lib\Encode\Detect\Detector.xs(79) : warning C4267: 'argument' : conver +sion from 'size_t' to 'PRUint32', possible loss of data lib\Encode\Detect\Detector.xs(109) : warning C4267: 'argument' : conve +rsion from 'size_t' to 'PRUint32', possible loss of data

    At that point, reissuing the nmake ought to allow things to complete--but it doesn't:

    C:\Perl64\packages\Encode-Detect-1.01>nmake Microsoft (R) Program Maintenance Utility Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. C:\Perl64\bin\perl.exe Build --makefile_env_macros 1 ExtUtils::Mkbootstrap::Mkbootstrap('blib\arch\auto\Encode\Detect\Detec +tor\Detector.bs') Generating script 'lib\Encode\Detect\Detect.lds' link @"lib\Encode\Detect\Detect.lds" -out:"blib\arch\auto\Encode\Detec +t\Detector\Detector.dll" LINK : warning LNK4044: unrecognized option '/lstdc++'; ignored Detect.def : error LNK2001: unresolved external symbol boot_Encode__De +tect Detect.def : error LNK2001: unresolved external symbol boot_Encode__De +tect lib\Encode\Detect\Detect.lib : fatal error LNK1120: 2 unresolved exter +nals mt -nologo -manifest "lib\Encode\Detect\Detect.dll.manifest" -outputre +source:"blib\arch\auto\Encode\Detect\Detector\Detector.dll";2 lib\Encode\Detect\Detect.dll.manifest : general error c1010070: Failed + to load and parse the manifest. The system cannot find the file spec +ified. Manifying blib\lib/Encode/Detect.pm -> blib\libdoc\Encode.Detect.3 Manifying blib\lib/Encode/Detect/Detector.pm -> blib\libdoc\Encode.Det +ect.Detector.3 HTMLifying blib\lib\Encode\Detect.pm -> blib\libhtml\site\lib\Encode\D +etect.html Build: blib\lib\Encode\Detect.pm: cannot resolve L<Encode> in paragrap +h 18. HTMLifying blib\lib\Encode\Detect\Detector.pm -> blib\libhtml\site\lib +\Encode\Detect\Detector.html

    And I haven't been able to hack my way past that one because again, the autogenerate linker response file: lib\Encode\Detect\Detect.lds is deleted automatically (why?), and it happens too fast for me to be able to intervene.

    So, your only choice is to try and navigate that purile maze of OO dark, twisty packages to try and work out what is generated inside that file. If you succeed in doing that, then you might stand some chance of working out why it is wrong.

    Or you can throw the problem back at the authors of the module and the build process and wait until they decide who is in the wrong and put it right. Say, 3 years from now if you are lucky!


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      The file compiles clean ... if you add option -TP to cause the compiler to treat the file as C++ .

      Easiest way to achieve that is to start the build process with perl Makefile.PL CC="cl -TP".
      For me, that allows Encode-Detect-1.01 to build ok (though I first had to copy the 2 header files that are in the 'include' folder into the 'src' folder). However, I strike runtime problems when running the test suite:
      Can't locate loadable object for module Encode::Detect::Detector
      I haven't the time at the moment to take a look at what's going wrong there. It's the same problem if I build with MinGW (starting with perl Makefile.PL CC="g++").

      Cheers,
      Rob

        That adds the -TP to the compiler commands for every file, rather than just the one that needs it. In this case, that doesn't seem to prevent the rest from compiling ok, but is that always true?

        But I don't see how to use that syntax to remove unneeded options?

        Didn't you see all the noise and errors that I'm seeing at the linker stage?

        Using response files instead of huge command lines is a step forward over EU::MM--but automatically deleting them so the programmer cannot look to see what options were used and perhaps try adjusting them, before sitting down to try and work out how to pursuade build.pl to produce what you've discovered works, is three steps backward.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Cannot compile Encode::Detect on Windows
by agrundma (Novice) on Apr 19, 2009 at 16:07 UTC
    Here is the solution. Note that I was building version 1.00 for various reasons but the same procedure should work for 1.01. I was using ActiveState 5.10.0 build 1004 and MSVC 2005 Pro.

    Replace the Module::Build Makefile.PL with an EU::MM one:

    #!/usr/bin/perl use strict; use ExtUtils::MakeMaker qw(WriteMakefile); my @INC = (' -Isrc -Iinclude'); WriteMakefile( NAME => 'Encode::Detect::Detector', VERSION_FROM => 'Detector.pm', PREREQ_PM => {}, ABSTRACT_FROM => 'Detector.pm', AUTHOR => '', INC => join(' ', @INC), C => [ glob 'src/*.cpp Detector.c' ], H => [ glob 'src/*.h' ], OBJECT => q/$(O_FILES)/, );
    Run Makefile.PL with CC var to enable C++ mode:
    $ perl Makefile.PL CC="cl -TP" $ nmake
    This will fail because it's looking for *.obj files in the src directory but they were built in the main directory.
    $ copy *.obj src $ nmake
    This will compile everything, but not copy Encode/Detect.pm to the correct place.
    $ copy Detect.pm blib\lib\Encode $ nmake test
    Done! There is almost certainly a way within Makefile.PL to work around the last 2 issues, but I didn't want to spend any more time on it.

Re: Cannot compile Encode::Detect on Windows
by syphilis (Archbishop) on Apr 19, 2009 at 18:42 UTC
    Hi,
    Here's a hack to build and install Encode-Detect-1.01 from source.

    1) Copy include/nscore.h and include/prmem.h to src/nscore.h and src/prmem.h
    2) Move Detect.pm from the top level source folder to 'lib/Encode/Detect.pm'. (You'll need to first create the lib/Encode directory.)
    3) In Build.PL change  dist_version_from => 'Detect.pm', to dist_version_from => 'lib/Encode/Detect.pm', 4) In the MANIFEST file change Detect.pm to lib/Encode/Detect.pm.
    5) Create My_Makefile.PL in the top level source folder (alongside existing Makefile.PL)

    My_Makefile.PL looks like this:
    use ExtUtils::MakeMaker; use Config; die "Wrong platform" if $Config{cc} ne 'cl' && $Config{cc} ne 'gcc'; WriteMakefile( NAME => 'Encode::Detect::Detector', CC => $Config{cc} eq 'cl' ? 'cl -TP' : 'g++', VERSION_FROM => 'Detector.pm', LIBS => $Config{make} eq 'nmake' ? '-L. -lns': '-L./src -lns', INC => '-I./src', );
    With Microsoft Compilers and nmake:
    Then build the library by running, in turn:
    a) perl Makefile.PL CC="cl -TP"
    b) nmake (terminates with error, but compiles the src/*.cpp files)
    c) lib /out:libns.lib *.obj
    d) nmake realclean (restores to what we started with + libns.lib + object files)
    Now that we have the library, let's build the module:
    e) perl My_Makefile.PL
    f) nmake test (should pass test suite)
    g) nmake install
    h) nmake realclean (to return to what we started with)

    With MinGW and dmake:
    Then build the library by running, in turn:
    a) perl Makefile.PL CC=g++
    b) dmake (terminates with error, but compiles the src/*.cpp files)
    c) cd src
    d) ar -rc libns.a *.o
    e) ranlib libns.a
    f) cd ..
    g) dmake realclean (restores to what we started with + src/libns.a)
    Now that we have the library, let's build the module:
    h) perl My_Makefile.PL
    i) dmake test (should pass test suite)
    j) dmake install
    k) dmake realclean (to return to what we started with + src/libns.a)

    Note that, for me, when building with nmake, the object files were all built in the top level source folder (instead of the 'src' folder, as happens with dmake). I can't guarantee that the behaviour in this regard will be the same for all versions of EU::MM - if it differs you will need to modify the above instructions acccordingly.

    Cheers,
    Rob
      This doesn't seem to work with the latest ActivePerl (5.10.1.1007)

      Executing perl Makefile.PL CC=g++ reports
      C:\Packages\Encode-Detect-1.01>perl Makefile.PL CC="cl -TP" # running Build.PL --config cc=cl -TP cl : Command line warning D9035 : option 'o' has been deprecated and w +ill be rem oved in a future release compilet-1026621440.c 'dlltool' is not recognized as an internal or external command, operable program or batch file. LINK : warning LNK4044: unrecognized option '/o'; ignored LINK : warning LNK4044: unrecognized option '/Wl,--base-file,C:\DOCUME +~1\VMUser\ LOCALS~1\Temp\compilet.base'; ignored LINK : warning LNK4044: unrecognized option '/Wl,--image-base,0xa03000 +0'; ignore d LINK : fatal error LNK1181: cannot open input file 'C:\DOCUME~1\VMUser +\LOCALS~1\ Temp\compilet.dll' 'dlltool' is not recognized as an internal or external command, operable program or batch file. LINK : warning LNK4044: unrecognized option '/o'; ignored LINK : warning LNK4044: unrecognized option '/Wl,--image-base,0xa03000 +0'; ignore d LINK : fatal error LNK1181: cannot open input file 'C:\DOCUME~1\VMUser +\LOCALS~1\ Temp\compilet.dll' Creating new 'MYMETA.yml' with configuration results Creating new 'Build' script for 'Encode-Detect' version '1.01'

      Not sure if this is already an issue but following the guidelines above the nmake test fails and finally trying to make install reports this:
      blib\arch\auto\Encode\Detect\Detector\Detector.dll : fatal error LNK11 +20: 5 unre solved externals NMAKE : fatal error U1077: '"c:\Program Files\Microsoft Visual Studio +9.0\VC\BIN \link.EXE"' : return code '0x460' Stop.

      It's a pity since it was working fine under perl 5.8.8
Re: Cannot compile Encode::Detect on Windows
by stonecolddevin (Parson) on Apr 16, 2009 at 18:16 UTC
    Any workarounds?

    Buy a Mac.

    :-D

    meh.