Perl Inline C code inside nginx Perl module
Ondrej Jombik
jombik at platon.org
Sun Apr 15 17:01:42 UTC 2018
On Fri, 13 Apr 2018, Maxim Dounin wrote:
>> As you can see in my example, I am not even using or calling test_fnc()
>> yet. But Perl code simply fails on startup with this error message:
>>
>> -- Unit nginx.service has begun starting up.
>> nginx[20011]: nginx: [emerg] require_pv("inlinetest.pm") failed: "Running Mkbootstrap for inlinetest_0cff
>> nginx[20011]: chmod 644 "inlinetest_0cff.bs"
>> nginx[20011]: "/usr/bin/perl" "/usr/share/perl/5.24/ExtUtils/xsubpp" -typemap "/usr/share/perl/5.24/ExtUt
>> nginx[20011]: x86_64-linux-gnu-gcc -c -I"/" -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-alias
>> nginx[20011]: x86_64-linux-gnu-gcc: error trying to exec 'cc1': execvp: No such file or directory
>> nginx[20011]: Makefile:332: recipe for target 'inlinetest_0cff.o' failed
>
> The problem is that your PATH is empty when relevant compilation
> happens. You try to set it in the code using "$ENV{'PATH'} =
> ...", but it doesn't work as this happens _after_ "use Inline...",
> because "use ..." operators are executed at compile time in Perl,
> much like BEGIN{}.
>
> A simple fix would be to set PATH in a BEGIN{} block at compile
> time:
>
> BEGIN { $ENV{'PATH'} = '/bin/:/usr/bin/'; }
> use Inline ...
>
> Alternativel, you can use nginx "env" directive to set PATH or
> preserve it from original environment, see http://nginx.org/r/env.
Thanks Maxim, it worked like a charm.
Your help is very appreciated!
I prefer using BEGIN { $ENV{'PATH'} = ... } construction, because this
will have scope for Perl module only, while nginx "env" directive would
be nginx-wide. Is this assumption correct?
Also here is some unrelated additional info which may be useful for
someone in the future:
If Inine C code is in Perl module and your C code is in __DATA__/__C__
section, using "Inline->init" statement is neccessary. Also trailing
"1;" is important and obviously must be placed before __DATA__.
Example:
package PACKAGENAME;
use strict;
use warnings;
use base qw(Exporter);
use Carp;
use Exporter ();
use Inline 'C' => 'DATA',
name => 'PACKAGENAME';
Inline->init;
use vars qw(@EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
$VERSION = do { [ q$Revision: 30336 $ =~ /(\d+)/g ]->[0]; };
@EXPORT = qw( example_function_for_export );
@EXPORT_OK = qw( example_function_for_export );
%EXPORT_TAGS = qw();
1;
__DATA__
__C__
/* here goes your C code */
void example_function_for_export(int num)
{
fprintf(stderr, "%d\n", num);
}
--
Ondrej JOMBIK
Platon Technologies s.r.o., Hlavna 3, Sala SK-92701
+421222111321 - info at platon.net - http://platon.net
Read our latest blog:
https://blog.platon.sk/icann-sknic-tld-problemy/
My current location: Bratislava, Slovakia
My current timezone: +0100 GMT (CET)
(updated automatically)
More information about the nginx
mailing list