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

Hello everyone,

I've made a lot of distance in my project so far thanks to you people. Now I'm pretty sure that my code is right. However this time I have a problem which got me completely puzzled!!

The story is: I have a cgi file (sunucuya_yukle.cgi) written in Perl that uses Inline::C module (It uses cl.exe (VC6 version) to compile the C-code section). When I compile my code from the command line, buumm everything's there. No problemo! When I run the code by calling it from my web browser, which is the way this code is supposed to work, it gives me an error message as:

"cl.exe is not recognized as an internal or external command..."

although I have the environmental paths set correctly and I get no problems from the command-line. (cl can be run from inside any folder and perl.exe sees it and compiles the code successfully)

So what I tried is to go out to the command promt and compile the code myself and then call the cgi file from my browser. That time the browser gives me the error:

Had problems bootstrapping Inline module 'sunucuya_yukle_cgi_485e' Can't load 'C:\Apache_Uyg\_Inline\lib/auto/sunucuya_yukle_cgi_485e/sun +ucuya_yukle_cgi_485e.dll' for module sunucuya_yukle_cgi_485e: load_fi +le:Specified module could not be found at C:/Perl/lib/DynaLoader.pm l +ine 201. at C:/Perl/site/lib/Inline.pm line 500 at C:/Apache_Uyg/sunucuya_yukle.cgi line 8 BEGIN failed--compilation aborted at C:/Apache_Uyg/sunucuya_yukle.cgi +line 142.

So any suggestions on how to solve this issue?? I am using Perl 5.10, Apache 2.2.8 and mod_perl 2.0.4.

Thanks in advance!

By the way the dll file seen above in the error message is successfully created once the code is compiled from the command-line. And it resides in the directory it's supposed to. The program runs perfectly from the command line

Replies are listed 'Best First'.
Re: Web Browser fails to compile my code
by almut (Canon) on May 21, 2008 at 00:42 UTC

    I would start to debug the issue by replacing your non-working CGI script with a very simple script which just dumps the environment. Then compare the output you get from within the webserver with what you get when you run the same CGI script from the command line.

    A default Apache installation even comes with such a script, called printenv (written in Perl), so you don't have to write it yourself.

Re: Web Browser fails to compile my code
by MidLifeXis (Monsignor) on May 20, 2008 at 21:52 UTC

    My guess is that the compiler is not found or available to the user that the web server runs as. Command line is not usually the same environment as a service.

    --MidLifeXis

      Well I don't know if I got you exactly right but I have to mention that I am running the tests on localhost. So this is the same computer.
        So this is the same computer.

        Did you try it with the same user account under which your web server runs? This is almost always a permissions issue. Running the program successfully from your user account tells you only that the program runs, not that it will run from the web server.

Re: Web Browser fails to compile my code
by BrowserUk (Patriarch) on May 21, 2008 at 01:02 UTC
      Hey... yes it is running as a service and I see "Local System" there
        yes it is running as a service and I see "Local System" there

        Then, as identified by those above, your script is running under a different account ("Local Service") when run from Apache2 than when you are running it from the command line. Hence it is subject to different permissions.

        You need to change the account Apache2 is run as:

        Right click the Apache2 service line, click "Properties", then the "Log on" tab, then "This account" and enter (or select) a username and password.

        And ensure that the user you choose has appropriate permissions (NOT an Administrator account!).

        But be aware! If this is an external facing machine, changing these permissions can expose your machine to intrusions. If you don't know what you're doing, ask someone who does. (Eg. Your local SysAdmin).

        Or, move all the files (The script itself plus all the Inline::C temporary directories and files) underneath your script-enabled Apache cgi-bin directory. But as I always found Apache configuration too messy to bother with, you'll need someone else to tell you how to do that.


        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: Web Browser fails to compile my code
by tachyon-II (Chaplain) on May 21, 2008 at 01:06 UTC

    Further to the above, probably the quickest fix is just to grab the Inline generated XS out of /build and use that directly (ie drop Inline out of the equation). All you need to go with the XS is a very short .pm to Dynaload it. h2xs will generated a stub XS example for you. Just paste in the autogenerated inline C XS and the INLINE.h and it should compile and install fine. Then in the scipt just use the module as normal. This will work and is almost certainly a more reliable solution as you have removed an abstraction layer.

      Now this is what I was thinking: build a proper XS module instead of using the Inline::C shortcut. No reason to force compilation on the web server process, especially if it doesn't work properly anyway.

      As a general question, I was wondering how Inline::C is used in production applications. My instinct is that Inline::C is more of a helper/get-me-started module, not something to be used in the final shipped application. Seeing how the OP solved the original problem confirms it for me: library and header include paths shouldn't be hard-coded in the Perl code; stuff like that belongs in a build process.

      On the other hand, my impression is that Inline::C is a very popular module. Is it accepted practice to include C code using it? Would I find modules on CPAN that depend on Inline::C?

      We do have some Perl at $work, but mostly just for utility scripts, and we've never had to write any C code. I'm curious what the general accepted practice is in the Perl community.

        You can use Google to "grep" cpan site:cpan.org/src "use Inline C" returns 30 results (click the last button to make Google find the real number, not the estimate). About 1/2 are .pm modules using Inline C, so the answer is not very many.

        h2xs is a powerful tool worth looking into.

        There is a moduleInlineX::XS that converts Inline::C code to XS although I have not tried it. There are also InlineX::C2XS InlineX::CPP2XS for C++

Re: Web Browser fails to compile my code
by Anonymous Monk on May 21, 2008 at 00:44 UTC

    I think this is likely to be a bug with Inline/Apache. When you use Inline::C what happens under the covers the first time you run it is rather complicated. In a nutshell your code gets parsed, converted to XS/C and then that gets compiled. The generated XC/C is found in cwd/_Inline/build/script_name_xxxx/. The actual executable objects are found in cwd/_Inline/lib/script_name_xxxx/ where the xxxx is the same as the build name.

    At runtime Inline looks to see if it needs to be compiled, and if so runs a compile then execute. If it has already been compiled it just executes.

    I can see multiple issues. First if you have run it you should not need cl.exe as it has already been compiled. The fact that your browser can't find cl.exe but you obviously can (it runs from the command line) indicates you are running with different paths to the web server.

    Anyway the server/perl should not need to compile this once it has been run off the command line once. If you look at the can't load statement you will see an issue with the path - it has \ and / path separators. As you checked to ensure sunucuya_yukle_cgi_485e.dll is there I wounder if a quick hack in Dynaloader to change the \ to / would fix it?

    foreach (@INC) { s!\\!/!g; # apachify path Win32 my $dir = "$_/auto/$modpname"; # here is the \ / problem next unless -d $dir; # skip over uninteresting directories # check for common cases to avoid autoload of dl_findfile my $try = "$dir/$modfname.dll";
Re: Web Browser fails to compile my code
by aykun81 (Sexton) on May 21, 2008 at 13:02 UTC

    Hello everyone! I have solved the issue and here is how:

    First of all I followed the advice which said run printenv.pl both on command line and in a web browser and I saw that the env. variable path had different content. So I copied all the path information from my private windows account env. vars to system env. vars. I also added the folder which is named /MSVC6/VC98/COMMON which contains, I believe, the dll files that cl.exe needs. This solved the compilation problem.

    Secondly, I started getting include errors which I hadn't been getting had I compiled the code from the command line. So I Included the folder(s) that contained the header files that could not be located by the compiler inside the expression:

    use Inline (C => Config => LIBS => '-LC:\OpenCV\lib -lcv.lib -lcxcore. +lib -lhighgui.lib -LC:\MSVC6\VC98\LIB', INC => '-IC:\MSVC6\VC98\INCLUDE');

    After all these, I was only getting the bootstrapping error which got automatically solved when I restarted the system.

    Thank you all for your invaluable efforts to help me. It's because of you that I could complete a difficult task for myself.

    Hvala!! Tesekkürker!! :)

Re: Web Browser fails to compile my code
by zentara (Cardinal) on May 21, 2008 at 13:05 UTC
    When I run the code by calling it from my web browser, which is the way this code is supposed to work, it gives me an error message as: "cl.exe is not recognized as an internal or external command..."

    One of the first rules they teach sysadmins, is NEVER let "the world", i.e. a web client, have access to a c compiler. Especially on win32. Thats a great way to get a virus.


    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      Thanks for the advice... I will keep it in mind! But I don't think that it will be a problem in this case in particular simply because this app will be running somewhat internally. So there will be no access to it from outside. But really thanks for the advice... I will consider it when it comes to security issues

        <p mode="sarcastic">What is your network again? I want to dump it into my border firewall's blacklist as a self protection mechanism</p>

        In all seriousness, it is worth the extra effort to learn to do it with minimal privileges up front, because it forces you to think of the reprecussions of the actions you are allowing the web server to accomplish.

        Too many times I have seen $management ask to have Joe External be able to use an "internal" application. Applications morph. Unless you limit up front what the application is able to do from a security standpoint (only what it needs to do), it is just too easy to make decisions later on without thinking through the implications.

        On the other hand, I started life as a security focused system admin, so I am a little more paranoid about those things.

        Update: And a P.S. "somewhat internal" means external, right? It is either 100% internal, or it is external.

        --MidLifeXis

        I'm curious. What does the C code do that you couln't do in Perl? Maybe you can avoid to use Inline at all.


        holli, /regexed monk/
Re: Web Browser fails to compile my code
by aykun81 (Sexton) on May 21, 2008 at 13:06 UTC
    It's actually: MSVC6\COMMON\MSDEV98\BIN