Skip to content

Commit

Permalink
Added selective linking and skipping options.
Browse files Browse the repository at this point in the history
Also added another sample to demonstrate this.
  • Loading branch information
quietfanatic committed Oct 15, 2009
1 parent 9bbee82 commit 8f3cfd6
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 11 deletions.
13 changes: 9 additions & 4 deletions Link/C.pm
Expand Up @@ -6,7 +6,7 @@ constant @HEADER_DIRS = <. /usr/include>, @*INC;
constant @LIBRARY_DIRS = <. /lib /usr/lib>, @*INC;
constant @LIBRARY_EXTS = '', <.so .so.0>;

sub link(*@files is copy, :$import?, :$verbose?, :$quiet?, :$cache = 1) {
sub link(*@files is copy, :$import?, :$verbose?, :$quiet?, :$cache = 1, :$link = *, :$skip?) {
our $already_called and die "Multiple calls to Link::C are not supported at this time, sorry.\nPlease put all your arguments in one call.\n";
$already_called = 1;
# make each argument point to a real file
Expand Down Expand Up @@ -36,7 +36,7 @@ sub link(*@files is copy, :$import?, :$verbose?, :$quiet?, :$cache = 1) {
warn "Not using cache" if $verbose;
warn "Reading headers and libraries" if $verbose;
# readh runs Link/C/readh.p5 and sets %functions
readh(@files);
readh(@files, :$link, :$skip);
warn "Generating code" if $verbose;
# this generates the linking code based on %functions
$linking_code = gen_linking_code(:$import);
Expand Down Expand Up @@ -107,7 +107,7 @@ sub resolve_library($f is rw) {
~ "\n";
}

sub readh(*@files is copy) {
sub readh(*@files is copy, :$link, :$skip) {
my $readh = join "/", ((@*INC, "..").first({"$_/Link/C/readh.p5" ~~ :e}), "Link/C/readh.p5");
our %functions;
for @files {
Expand All @@ -119,10 +119,15 @@ sub readh(*@files is copy) {
my $err = slurp $tmperr;
unlink $tmperr;
die $err if $err;
my @skip = $skip ~~ Array ?? @($skip) !! $skip;
my @link = $link ~~ Array ?? @($link) !! $skip;
for $result.split("\n") {
next when "";
my @r = .split(' : ');
push (%functions{shift @r} //= []), [@r];
next if @r[1] ~~ any(@skip)
if @r[1] ~~ any(@link) {
push (%functions{shift @r} //= []), [@r];
}
}
}

Expand Down
27 changes: 20 additions & 7 deletions README
Expand Up @@ -7,27 +7,34 @@ Only works with Rakudo.
USAGE:

use Link::C;
Link::C::link <library-file header.h>;
Link::C::link <library_file header.h>;
my $result = C::my_function("arguments", 42);


OPTIONS: (give to Link::C::link)

:import($matcher, ...)
:import($matcher => $subst, ...)
:link($match, ...) (Default: *)
- Link only functions whose names match $match.
Useful if you're interested in only a small subset of a large library
that would take a long time to process.
:skip($match, ...)
- Do not link functions whose names match $match.
This overrides :link.
:import($match, ...)
:import($match => $subst, ...)
- Import functions into global namespace
By default functions are put into the C:: namespace. Using this option
will import the functions whose names match $matcher, optionally
replacing parts of their name with $subst. You can include namespace
seperators in the string. This is mainly so you can say:
will import the functions whose names match $match, optionally
replacing those parts of their name with $subst. You can include
namespace seperators in the string. This is mainly so you can say:
:import(/^SDL_/ => 'SDL::')
or such, and call SDL::Init instead of C::SDL_Init.
Using :import(*) will put all functions into the global namespace.
:verbose
- Print status messages to STDERR for the impatient.
:quiet
- Disable non-fatal warnings such as when caching fails.
:cache (Default)
:cache (Default: True)
- Cache the linking code.
:!cache
- Do not cache the linking code.
Expand Down Expand Up @@ -60,3 +67,9 @@ cached at $yourprogram.linkc-cache.pm and $yourprogram.linkc-cache.pir. Once
cached there will be minimal overhead. For even shorter load times, do this:
$ perl6 --target=pir Link/C.pm > Link/C.pir

Right now, Link::C::link can only be called once, because the cache would get
overwritten. However, you can give all your libraries and headers to Link::C
at once, and it will automatically link each function to the right library.
This will probably be faster than doing it in multiple passes anyway.

Link::C assumes your library files are in ELF format.
8 changes: 8 additions & 0 deletions sample-readline.pl
@@ -0,0 +1,8 @@
use v6;
use Link::C;
Link::C::link <libreadline readline/readline.h>, :link(<rl_initialize readline>), :import(*);

rl_initialize;
while my $line = readline "Flip: " {
say $line.flip;
}

0 comments on commit 8f3cfd6

Please sign in to comment.