# -*- cperl -*- # Makefile.PL - tastes great, less filling (than h2ph) # # Copyright (c) 2000 Cepstral LLC. All rights Reserved. # # This module is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # Written by David Huggins-Daines use ExtUtils::MakeMaker; use Getopt::Long; use strict; my %constants = (ioctls => [qw( SNDCTL_DSP_RESET SNDCTL_DSP_SYNC SNDCTL_DSP_SPEED SNDCTL_DSP_STEREO SNDCTL_DSP_GETBLKSIZE SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_CHANNELS SNDCTL_DSP_POST SNDCTL_DSP_SUBDIVIDE SNDCTL_DSP_SETFRAGMENT SNDCTL_DSP_GETOSPACE SNDCTL_DSP_GETISPACE SNDCTL_DSP_NONBLOCK SNDCTL_DSP_GETCAPS SNDCTL_DSP_GETFMTS SNDCTL_DSP_SETFMT SNDCTL_DSP_GETTRIGGER SNDCTL_DSP_SETTRIGGER SNDCTL_DSP_GETIPTR SNDCTL_DSP_GETOPTR SNDCTL_DSP_MAPINBUF SNDCTL_DSP_MAPOUTBUF SNDCTL_DSP_SETSYNCRO SNDCTL_DSP_SETDUPLEX SNDCTL_DSP_GETODELAY SNDCTL_DSP_GETCHANNELMASK SNDCTL_DSP_BIND_CHANNEL SNDCTL_DSP_PROFILE SOUND_PCM_READ_RATE SOUND_PCM_READ_CHANNELS SOUND_PCM_READ_BITS SOUND_PCM_READ_FILTER SOUND_MIXER_READ_VOLUME SOUND_MIXER_READ_RECSRC SOUND_MIXER_READ_DEVMASK SOUND_MIXER_READ_RECMASK SOUND_MIXER_READ_STEREODEVS SOUND_MIXER_READ_CAPS SOUND_MIXER_WRITE_VOLUME SOUND_MIXER_WRITE_RECSRC SOUND_MIXER_INFO SOUND_MIXER_AGC SOUND_MIXER_3DSE SOUND_MIXER_PRIVATE1 SOUND_MIXER_PRIVATE2 SOUND_MIXER_PRIVATE3 SOUND_MIXER_PRIVATE4 SOUND_MIXER_PRIVATE5 SOUND_MIXER_GETLEVELS SOUND_MIXER_SETLEVELS OSS_GETVERSION )], mixer => [qw( SOUND_MIXER_NRDEVICES SOUND_MIXER_VOLUME SOUND_MIXER_BASS SOUND_MIXER_TREBLE SOUND_MIXER_SYNTH SOUND_MIXER_PCM SOUND_MIXER_SPEAKER SOUND_MIXER_LINE SOUND_MIXER_MIC SOUND_MIXER_CD SOUND_MIXER_IMIX SOUND_MIXER_ALTPCM SOUND_MIXER_RECLEV SOUND_MIXER_IGAIN SOUND_MIXER_OGAIN SOUND_MIXER_LINE1 SOUND_MIXER_LINE2 SOUND_MIXER_LINE3 SOUND_MIXER_DIGITAL1 SOUND_MIXER_DIGITAL2 SOUND_MIXER_DIGITAL3 SOUND_MIXER_PHONEIN SOUND_MIXER_PHONEOUT SOUND_MIXER_VIDEO SOUND_MIXER_RADIO SOUND_MIXER_MONITOR SOUND_MIXER_NONE SOUND_ONOFF_MIN SOUND_ONOFF_MAX SOUND_MIXER_RECSRC SOUND_MIXER_DEVMASK SOUND_MIXER_RECMASK SOUND_MIXER_CAPS SOUND_CAP_EXCL_INPUT SOUND_MIXER_STEREODEVS SOUND_MIXER_OUTSRC SOUND_MIXER_OUTMASK )], formats => [qw( AFMT_QUERY AFMT_MU_LAW AFMT_A_LAW AFMT_IMA_ADPCM AFMT_U8 AFMT_S16_LE AFMT_S16_BE AFMT_S16_NE AFMT_S8 AFMT_U16_LE AFMT_U16_BE AFMT_MPEG AFMT_AC3 )], caps => [qw( DSP_CAP_REVISION DSP_CAP_DUPLEX DSP_CAP_REALTIME DSP_CAP_BATCH DSP_CAP_COPROC DSP_CAP_TRIGGER DSP_CAP_MMAP DSP_CAP_MULTI DSP_CAP_BIND )], bind => [qw( DSP_BIND_QUERY DSP_BIND_FRONT DSP_BIND_SURR DSP_BIND_CENTER_LFE DSP_BIND_HANDSET DSP_BIND_MIC DSP_BIND_MODEM1 DSP_BIND_MODEM2 DSP_BIND_I2S DSP_BIND_SPDIF )], misc => [qw( PCM_ENABLE_INPUT PCM_ENABLE_OUTPUT APF_NORMAL APF_NETWORK APF_CPUINTENS)], ); my ($khdrs, $ohdrs); GetOptions('kernel-headers=s' => \$khdrs, 'oss-headers=s' => \$ohdrs); my @possible_hdrdirs; if (defined $khdrs or defined $ohdrs) { @possible_hdrdirs = ((defined $khdrs ? "$khdrs/linux" : ()), $ohdrs); } else { @possible_hdrdirs = qw(/usr/local/include /usr/local/include/sys /usr/include /usr/include/sys /usr/include/linux /usr/src/linux/include/linux); } use vars qw($SOUNDCARD_H); foreach my $dir (@possible_hdrdirs) { if (-r "$dir/soundcard.h") { $SOUNDCARD_H = "$dir/soundcard.h"; last; } } unless (defined($SOUNDCARD_H)) { local $" = "\n"; print <<"EOF"; No OSS header files could be found in any of the following directories: @possible_hdrdirs You can use the --kernel-headers option to specify the location of your Linux kernel header files (e.g. /home/foo/linux/include), or the --oss-headers option to specify a directory containing Open Sound System header files. EOF exit 1; } print "Finding constants and values, this may take a while...\n"; use vars qw($CC $NO_DASH_INCLUDE); $CC = $ENV{CC} || 'cc'; $NO_DASH_INCLUDE = 0; unlink 'conftest'; if (system($CC, '-include', $SOUNDCARD_H, 'conftest.c', '-o', 'conftest') != 0) { $NO_DASH_INCLUDE = 1; if (system($CC, 'conftest.c', '-o', 'conftest') != 0) { # Give up print <<"EOF"; Compiling test program: $CC -i $SOUNDCARD_H conftest.c -o conftest $CC conftest.c -o conftest Failed with status $?. You can change the default compiler by setting the \$CC environment variable in your shell. EOF exit 1; } } unlink 'conftest'; sub check_const { my @cmd; unlink 'get-constants.c'; open TEMPL, "get-constants.c" or die "Could not open get-constants.c: $!"; if ($NO_DASH_INCLUDE) { open H, "<$SOUNDCARD_H" or die "Could not open $SOUNDCARD_H: $!"; while () { print TEST $_; } close H; @cmd = ($CC, 'get-constants.c', '-o', 'get-constants'); } else { @cmd = ($CC, '-include', $SOUNDCARD_H, 'get-constants.c', '-o', 'get-constants'); } while () { if (m,/\* INSERT CONSTANTS HERE \*/,) { foreach my $const (@_) { print TEST qq/{ "$const", $const },\n/; } } else { print TEST $_; } } close TEMPL; close TEST; if (my $pid = fork) { waitpid $pid, 0; if ($?) { unlink 'get-constants.c', 'get-constants'; return undef; } } else { close STDERR; exec @cmd or die "exec failed: $!"; } my @ret; open PROG, './get-constants|' or die "Could not open pipe: $! $?"; while () { chomp; my ($const, $val) = split /:/; push @ret, $val; } unlink 'get-constants.c', 'get-constants'; return (@ret == 1) ? $ret[0] : @ret; } my (@constmap, %valid); foreach my $t (keys %constants) { foreach my $c (@{$constants{$t}}) { { print "Checking for $c... "; local $|=1; } my $val = check_const($c); if (defined $val) { print "$val.\n"; push @constmap, [$c => $val]; $valid{$t}{$c} = 1; } else { print "not found.\n"; } } } unlink 'OSS/Constants.pm'; mkdir 'OSS', 0755; open CONFMOD, '>OSS/Constants.pm' or die "Could not open OSS/Constants.pm: $!"; # Random header stuff print CONFMOD <<'EOP'; package Audio::OSS; use strict; use vars qw(@EXPORT_OK %EXPORT_TAGS @CONSTANTS); push @EXPORT_OK, qw( EOP # Now the constant names foreach (@constmap) { print CONFMOD "\t$_->[0]\n"; } print CONFMOD <<'EOP'; ); EOP foreach my $t (keys %constants) { print CONFMOD "\$EXPORT_TAGS{'$t'} = [qw(\n"; foreach my $c (@{$constants{$t}}) { print CONFMOD "\t$c\n" if $valid{$t}{$c}; } print CONFMOD "\t)];\n"; } print CONFMOD <<'EOP'; @CONSTANTS = ( EOP # And their values foreach (@constmap) { print CONFMOD "\t[ $_->[0] => $_->[1] ],\n"; } # And some cruft to define them for us print CONFMOD <<'EOP'; ); sub make_const { my ($const, $val) = @_; no strict 'refs'; *$const = sub () { $val }; } foreach (@CONSTANTS) { make_const(@$_); } 1; EOP close CONFMOD; WriteMakefile( NAME => 'Audio::OSS', VERSION_FROM => 'OSS.pm', C => [], # NO MAKEMAKER, THAT'S WRONG clean => { FILES => 'conftest get-constants.c get-constants OSS/Constants.pm' }, );