2 # ====================================================================
3 # The Apache Software License, Version 1.1
5 # Copyright (c) 2000-2001 The Apache Software Foundation. All rights
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
12 # 1. Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
15 # 2. Redistributions in binary form must reproduce the above copyright
16 # notice, this list of conditions and the following disclaimer in
17 # the documentation and/or other materials provided with the
20 # 3. The end-user documentation included with the redistribution,
21 # if any, must include the following acknowledgment:
22 # "This product includes software developed by the
23 # Apache Software Foundation (http://www.apache.org/)."
24 # Alternately, this acknowledgment may appear in the software itself,
25 # if and wherever such third-party acknowledgments normally appear.
27 # 4. The names "Apache" and "Apache Software Foundation" must
28 # not be used to endorse or promote products derived from this
29 # software without prior written permission. For written
30 # permission, please contact apache@apache.org.
32 # 5. Products derived from this software may not be called "Apache",
33 # nor may "Apache" appear in their name, without prior written
34 # permission of the Apache Software Foundation.
36 # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 # DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40 # ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 # ====================================================================
50 # This software consists of voluntary contributions made by many
51 # individuals on behalf of the Apache Software Foundation. For more
52 # information on the Apache Software Foundation, please see
53 # <http://www.apache.org/>.
64 my $prefix = "@prefix@";
65 my $CFG_PREFIX = $prefix;
67 # read the configuration variables once
69 get_config_vars("$prefix/build/config_vars.mk",\%config_vars);
71 my $exec_prefix = get_vars("exec_prefix");
72 my $CFG_TARGET = get_vars("progname");
73 my $CFG_SYSCONFDIR = get_vars("sysconfdir");
74 my $CFG_CFLAGS = join ' ', map { get_vars($_) }
75 qw(SHLTCFLAGS CFLAGS NOTEST_CPPFLAGS EXTRA_CPPFLAGS EXTRA_CFLAGS);
76 my $includedir = get_vars("includedir");
77 my $CFG_INCLUDEDIR = eval qq("$includedir");
78 my $CFG_CC = get_vars("CC");
79 my $libexecdir = get_vars("libexecdir");
80 my $CFG_LIBEXECDIR = eval qq("$libexecdir");
81 my $bindir = get_vars("bindir");
82 my $CFG_SBINDIR = eval qq("$bindir");
84 my %internal_vars = map {$_ => 1}
85 qw(TARGET CC CFLAGS CFLAGS_SHLIB LD_SHLIB LDFLAGS_SHLIB LIBS_SHLIB
86 PREFIX SBINDIR INCLUDEDIR LIBEXECDIR SYSCONFDIR);
89 ## parse argument line
92 # defaults for parameters
110 # this subroutine is derived from Perl's getopts.pl with the enhancement of
111 # the "+" metacharater at the format string to allow a list to be build by
112 # subsequent occurance of the same option.
114 my ($argumentative, @ARGV) = @_;
119 my @args = split / */, $argumentative;
120 while (@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) {
121 my ($first, $rest) = ($1,$2);
126 my $pos = index($argumentative,$first);
128 if ($args[$pos+1] eq ':') {
132 error("Incomplete option: $first (needs an argument)");
135 $rest = shift(@ARGV);
137 eval "\$opt_$first = \$rest;";
139 elsif ($args[$pos+1] eq '+') {
143 error("Incomplete option: $first (needs an argument)");
146 $rest = shift(@ARGV);
148 eval "push(\@opt_$first, \$rest);";
151 eval "\$opt_$first = 1";
161 error("Unknown option: $first");
171 return ($errs == 0, @ARGV);
175 print STDERR "Usage: apxs -g [-S <var>=<val>] -n <modname>\n";
176 print STDERR " apxs -q [-S <var>=<val>] <query> ...\n";
177 print STDERR " apxs -c [-S <var>=<val>] [-o <dsofile>] [-D <name>[=<value>]]\n";
178 print STDERR " [-I <incdir>] [-L <libdir>] [-l <libname>] [-Wc,<flags>]\n";
179 print STDERR " [-Wl,<flags>] <files> ...\n";
180 print STDERR " apxs -i [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n";
181 print STDERR " apxs -e [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n";
187 ($rc, @ARGV) = &Getopts("qn:gco:I+D+L+l+W+S+eiaA", @ARGV);
188 &usage if ($rc == 0);
189 &usage if ($#ARGV == -1 and not $opt_g);
190 &usage if (not $opt_q and not ($opt_g and $opt_n) and not $opt_i and not $opt_c and not $opt_e);
194 my $name = 'unknown';
195 $name = $opt_n if ($opt_n ne '');
199 foreach $opt_S (@opt_S) {
200 if ($opt_S =~ m/^([^=]+)=(.*)$/) {
203 my $oldval = eval "\$CFG_$var";
205 unless ($var and $oldval) {
206 print STDERR "apxs:Error: no config variable $var\n";
210 eval "\$CFG_${var}=\"${val}\"";
212 print STDERR "apxs:Error: malformatted -S option\n";
219 ## Initial shared object support check
221 my $httpd = get_vars("bindir") . "/" . get_vars("progname");
222 $httpd = eval qq("$httpd");
223 $httpd = eval qq("$httpd");
225 #allow apxs to be run from the source tree, before installation
226 if ($0 =~ m:support/apxs$:) {
227 ($httpd = $0) =~ s:support/apxs$::;
230 unless (-x "$httpd") {
231 error("$httpd not found or not executable");
235 unless (grep /mod_so/, `$httpd -l`) {
236 error("Sorry, no shared object support for Apache");
237 error("available under your platform. Make sure");
238 error("the Apache module mod_so is compiled into");
239 error("your server binary `$httpd'.");
244 my ($file, $rh_config) = @_;
246 open IN, $file or die "cannot open $file: $!";
248 if (/^\s*(.*?)\s*=\s*(.*)$/){
249 $rh_config->{$1} = $2;
260 if (exists $config_vars{$arg} or exists $config_vars{lc $arg}) {
261 my $val = exists $config_vars{$arg}
263 : $config_vars{lc $arg};
265 $result .= eval "qq($val)";
270 if (exists $internal_vars{$arg} or exists $internal_vars{lc $arg}) {
271 my $val = exists $internal_vars{$arg} ? $arg : lc $arg;
272 $val = eval "\$CFG_$val";
273 $result .= eval "qq($val)";
278 error("Invalid query string `$arg'");
292 # helper function for executing a list of
293 # system command with return code checks
298 foreach $cmd (@cmds) {
302 error(sprintf "Command failed with rc=%d\n", $rc << 8);
310 ## SAMPLE MODULE SOURCE GENERATION
314 error("Directory `$name' already exists. Remove first");
318 my $data = join('', <DATA>);
319 $data =~ s|%NAME%|$name|sg;
320 $data =~ s|%TARGET%|$CFG_TARGET|sg;
322 my ($mkf, $mods, $src) = ($data =~ m|^(.+)-=#=-\n(.+)-=#=-\n(.+)|s);
324 notice("Creating [DIR] $name");
325 system("mkdir $name");
326 notice("Creating [FILE] $name/Makefile");
327 open(FP, ">${name}/Makefile") || die;
330 notice("Creating [FILE] $name/modules.mk");
331 open(FP, ">${name}/modules.mk") || die;
334 notice("Creating [FILE] $name/mod_$name.c");
335 open(FP, ">${name}/mod_${name}.c") || die;
338 notice("Creating [FILE] $name/.deps");
339 system("touch ${name}/.deps");
349 my $result = get_vars(@args);
355 ## SHARED OBJECT COMPILATION
358 # split files into sources and objects
371 # determine output file
375 $dso_file = $srcs[0];
376 $dso_file =~ s|\.[^.]+$|.la|;
378 elsif ($#objs > -1) {
379 $dso_file = $objs[0];
380 $dso_file =~ s|\.[^.]+$|.la|;
383 $dso_file = "mod_unknown.so";
390 # create compilation commands
393 my ($opt_Wc, $opt_I, $opt_D);
394 foreach $opt_Wc (@opt_W) {
395 $opt .= "$1 " if ($opt_Wc =~ m|^\s*c,(.*)$|);
397 foreach $opt_I (@opt_I) {
400 foreach $opt_D (@opt_D) {
403 my $cflags = "$CFG_CFLAGS";
408 $slo =~ s|\.c$|.slo|;
415 push(@cmds, "$prefix/build/libtool --silent --mode=compile $CFG_CC $cflags -I$CFG_INCLUDEDIR $opt -c -o $lo $s && touch $slo");
419 # create link command
425 my ($opt_Wl, $opt_L, $opt_l);
426 foreach $opt_Wl (@opt_W) {
427 if ($CFG_CC !~ m/gcc$/) {
428 $opt .= " $1" if ($opt_Wl =~ m|^\s*l,(.*)$|);
430 $opt .= " -W$opt_Wl";
433 foreach $opt_L (@opt_L) {
436 foreach $opt_l (@opt_l) {
440 push(@cmds, "$prefix/build/libtool --silent --mode=link $CFG_CC -o $dso_file -rpath $CFG_LIBEXECDIR -module -avoid-version $opt $lo");
442 # execute the commands
443 &execute_cmds(@cmds);
445 # allow one-step compilation and installation
446 if ($opt_i or $opt_e) {
447 @args = ( $dso_file );
451 if ($opt_i or $opt_e) {
453 ## SHARED OBJECT INSTALLATION
456 # determine installation commands
457 # and corresponding LoadModule/AddModule directives
463 if ($f !~ m#(\.so$|\.la$)#) {
464 error("file $f is not a shared object");
468 $t =~ s|^.+/([^/]+)$|$1|;
470 push(@cmds, "$prefix/build/libtool --mode=install cp $f $CFG_LIBEXECDIR/$t");
471 push(@cmds, "chmod 755 $CFG_LIBEXECDIR/$t");
474 # determine module symbolname and filename
476 if ($name eq 'unknown') {
479 $base =~ s|\.[^.]+$||;
481 open(FP, "<$base.c");
482 my $content = join('', <FP>);
484 if ($content =~ m|.*module\s+(?:AP_MODULE_DECLARE_DATA\s+)?([a-zA-Z0-9_]+)_module\s*=\s*.*|s) {
486 $filename = "$base.c";
487 $filename =~ s|^[^/]+/||;
491 if ($base =~ m|.*mod_([a-zA-Z0-9_]+)\..+|) {
494 $filename =~ s|^[^/]+/||;
498 error("Sorry, cannot determine bootstrap symbol name");
499 error("Please specify one with option `-n'");
503 if ($filename eq '') {
504 $filename = "mod_${name}.c";
506 my $dir = $CFG_LIBEXECDIR;
507 $dir =~ s|^$CFG_PREFIX/?||;
510 push(@lmd, sprintf("LoadModule %-18s %s", "${name}_module", "$dir$t"));
511 push(@amd, sprintf("AddModule %s", $filename));
514 # execute the commands
515 &execute_cmds(@cmds);
517 # activate module via LoadModule/AddModule directive
518 if ($opt_a or $opt_A) {
519 if (not -f "$CFG_SYSCONFDIR/$CFG_TARGET.conf") {
520 error("Config file $CFG_SYSCONFDIR/$CFG_TARGET.conf not found");
524 open(FP, "<$CFG_SYSCONFDIR/$CFG_TARGET.conf") || die;
525 my $content = join('', <FP>);
528 if ($content !~ m|\n#?\s*LoadModule\s+|) {
529 error("Activation failed for custom $CFG_SYSCONFDIR/$CFG_TARGET.conf file.");
530 error("At least one `LoadModule' directive already has to exist.");
536 $c = '#' if ($opt_A);
537 foreach $lmd (@lmd) {
538 my $what = $opt_A ? "preparing" : "activating";
539 if ($content !~ m|\n#?\s*$lmd|) {
540 $content =~ s|^(.*\n#?\s*LoadModule\s+[^\n]+\n)|$1$c$lmd\n|sg;
542 $content =~ s|^(.*\n)#?\s*$lmd[^\n]*\n|$1$c$lmd\n|sg;
544 $lmd =~ m|LoadModule\s+(.+?)_module.*|;
545 notice("[$what module `$1' in $CFG_SYSCONFDIR/$CFG_TARGET.conf]");
548 foreach $amd (@amd) {
549 if ($content !~ m|\n#?\s*$amd|) {
550 $content =~ s|^(.*\n#?\s*AddModule\s+[^\n]+\n)|$1$c$amd\n|sg;
552 $content =~ s|^(.*\n)#?\s*$amd[^\n]*\n|$1$c$amd\n|sg;
556 if (open(FP, ">$CFG_SYSCONFDIR/$CFG_TARGET.conf.new")) {
559 system("cp $CFG_SYSCONFDIR/$CFG_TARGET.conf $CFG_SYSCONFDIR/$CFG_TARGET.conf.bak && " .
560 "cp $CFG_SYSCONFDIR/$CFG_TARGET.conf.new $CFG_SYSCONFDIR/$CFG_TARGET.conf && " .
561 "rm $CFG_SYSCONFDIR/$CFG_TARGET.conf.new");
563 notice("unable to open configuration file");
570 print STDERR "apxs:Error: $_[0].\n";
574 print STDERR "$_[0]\n";
580 ## Makefile -- Build procedure for sample %NAME% Apache module
581 ## Autogenerated via ``apxs -n %NAME% -g''.
584 builddir=$(shell pwd)
585 top_srcdir=/home/rbb/apachebin4
586 top_builddir=/home/rbb/apachebin4/build
587 include /home/rbb/apachebin4/build/special.mk
593 # additional defines, includes and libraries
594 #DEF=-Dmy_define=my_value
595 #INC=-Imy/include/dir
596 #LIB=-Lmy/lib/dir -lmylib
599 all: local-shared-build
601 # install the shared object file into Apache
602 install: install-modules
606 -rm -f mod_%NAME%.o mod_%NAME%.lo mod_%NAME%.slo mod_%NAME%.la
610 lynx -mime_header http://localhost/%NAME%
612 # install and activate shared object by reloading Apache to
613 # force a reload of the shared object file
614 reload: install restart
616 # the general Apache start/restart/stop
626 mod_%NAME%.la: mod_%NAME%.slo
627 $(SH_LINK) -rpath $(libexecdir) -module -avoid-version mod_%NAME%.lo
628 DISTCLEAN_TARGETS = modules.mk
629 shared = mod_%NAME%.la
632 ** mod_%NAME%.c -- Apache sample %NAME% module
633 ** [Autogenerated via ``apxs -n %NAME% -g'']
635 ** To play with this sample module first compile it into a
636 ** DSO file and install it into Apache's modules directory
639 ** $ apxs -c -i mod_%NAME%.c
641 ** Then activate it in Apache's %TARGET%.conf file for instance
642 ** for the URL /%NAME% in as follows:
645 ** LoadModule %NAME%_module modules/mod_%NAME%.so
646 ** <Location /%NAME%>
650 ** Then after restarting Apache via
652 ** $ apachectl restart
654 ** you immediately can request the URL /%NAME% and watch for the
655 ** output of this module. This can be achieved for instance via:
657 ** $ lynx -mime_header http://localhost/%NAME%
659 ** The output should be similar to the following one:
662 ** Date: Tue, 31 Mar 1998 14:42:22 GMT
663 ** Server: Apache/1.3.4 (Unix)
665 ** Content-Type: text/html
667 ** The sample page from mod_%NAME%.c
671 #include "http_config.h"
672 #include "http_protocol.h"
673 #include "ap_config.h"
675 /* The sample content handler */
676 static int %NAME%_handler(request_rec *r)
678 if (strcmp(r->handler, "%NAME%")) {
681 r->content_type = "text/html";
684 ap_rputs("The sample page from mod_%NAME%.c\n", r);
688 static void %NAME%_register_hooks(apr_pool_t *p)
690 ap_hook_handler(%NAME%_handler, NULL, NULL, APR_HOOK_MIDDLE);
693 /* Dispatch list for API hooks */
694 module AP_MODULE_DECLARE_DATA %NAME%_module = {
695 STANDARD20_MODULE_STUFF,
696 NULL, /* create per-dir config structures */
697 NULL, /* merge per-dir config structures */
698 NULL, /* create per-server config structures */
699 NULL, /* merge per-server config structures */
700 NULL, /* table of config file commands */
701 %NAME%_register_hooks /* register hooks */