Permalink
Browse files

Merge branch 'rurban/pcre-dynext_libs-gh302'

  • Loading branch information...
2 parents 41a11f3 + ffc2be5 commit fa141227955afc4686fd88534d6fef4b2f2e45e2 @rurban rurban committed Jan 2, 2013
Showing with 126 additions and 7 deletions.
  1. +2 −0 ChangeLog
  2. +4 −1 config/init/hints/darwin.pm
  3. +3 −0 config/init/hints/openbsd.pm
  4. +77 −0 src/library.c
  5. +40 −6 t/library/lib_search_path.t
View
2 ChangeLog
@@ -11,6 +11,8 @@
+ Install libraries tgc.pbc, NCI/Utils.pbc, OpenGL/Math.pbc, PCT/Dumper.pbc,
postgres.pbc, ProfTest.pbc and ProfTest/*pbc, String/Utils.pbc, URI/Escape.pbc,
YAML/Dumper/Base.pbc, YAML/Dumper/Default.pbc
+ + New experimental PARROT_DYNEXT environment variable
+ + New experimental dynext_libs config entry (same as PARROT_DYNEXT)
- Build
+ Generate MANIFEST.generated, cleanup MANIFEST,
removed MANIFEST_configure.generated, add installation of forgotten files
View
5 config/init/hints/darwin.pm
@@ -95,6 +95,7 @@ sub runstep {
. $conf->data->get('share_ext')
. '"'
);
+ $darwin_selections{dynext_libs} = $flagsref->{dynext_libs} if $flagsref->{dynext_libs};
my $darwin_hints = "Darwin hints settings:\n";
for my $k (sort keys %darwin_selections) {
$darwin_hints .= sprintf(" %-24s => %s\n" => (
@@ -181,7 +182,7 @@ sub _probe_for_fink {
# regardless of where Fink itself is installed.
my $fink_conf = $defaults{fink_conf};
unless (-f $fink_conf) {
- $conf->debug("Fink configuration file not located\n");
+ $conf->debug("Fink configuration file $fink_conf not located\n");
return;
}
my $fink_conf_str = Parrot::BuildUtil::slurp_file($fink_conf);
@@ -212,6 +213,7 @@ sub _probe_for_fink {
linkflags => "-L$fink_lib_dir",
ldflags => "-L$fink_lib_dir",
ccflags => "-isystem $fink_include_dir",
+ dynext_libs => $fink_lib_dir."/",
);
return \%addl_flags;
}
@@ -235,6 +237,7 @@ sub _probe_for_macports {
linkflags => "-L$ports_lib_dir",
ldflags => "-L$ports_lib_dir",
ccflags => "-isystem $ports_include_dir",
+ dynext_libs => $ports_lib_dir."/",
);
return \%addl_flags;
}
View
3 config/init/hints/openbsd.pm
@@ -22,8 +22,10 @@ sub runstep {
}
my $ldflags = $conf->data->get('ldflags');
+ my $dynext_libs;
if ( $ldflags !~ m|-L/usr/local/lib\b| ) {
$ldflags .= ' -L/usr/local/lib';
+ $dynext_libs = '/usr/local/lib/';
}
$conf->data->set(
@@ -38,6 +40,7 @@ sub runstep {
libparrot_shared_alias => "libparrot$share_ext",
libparrot_soname => "-Wl,-soname=libparrot$share_ext.$version",
);
+ $conf->data->set( dynext_libs => $dynext_libs ) if $dynext_libs;
if ( ( split( m/-/, $conf->data->get('archname_provisional'), 2 ) )[0] eq 'powerpc' ) {
$conf->data->set( as => 'as -mregnames' );
View
77 src/library.c
@@ -28,6 +28,13 @@ dynext files (via C<loadlib>).
/* HEADERIZER BEGIN: static */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+static void add_env_paths(PARROT_INTERP,
+ ARGIN(PMC *libpath),
+ ARGIN(const STRING *envstr))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3);
+
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
static STRING * cnv_to_win32_filesep(PARROT_INTERP,
@@ -73,6 +80,10 @@ static STRING* try_load_path(PARROT_INTERP, ARGIN(STRING* path))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
+#define ASSERT_ARGS_add_env_paths __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(libpath) \
+ , PARROT_ASSERT_ARG(envstr))
#define ASSERT_ARGS_cnv_to_win32_filesep __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(path))
@@ -178,6 +189,14 @@ parrot_init_library_paths(PARROT_INTERP)
PARROT_LIB_PATH_DYNEXT, paths);
entry = CONST_STRING(interp, "dynext/");
VTABLE_push_string(interp, paths, entry);
+ { /* EXPERIMENTAL: add dynext path from environment */
+ STRING *dynext_libs = Parrot_getenv(interp, CONST_STRING(interp, "PARROT_DYNEXT"));
+ Parrot_warn_experimental(interp, "PARROT_DYNEXT environment variable is experimental");
+ if (!STRING_IS_NULL(dynext_libs) && !STRING_IS_EMPTY(dynext_libs)) {
+ add_env_paths(interp, paths, dynext_libs);
+ }
+ }
+
/* shared exts */
paths = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
@@ -215,6 +234,7 @@ Parrot_lib_update_paths_from_config_hash(PARROT_INTERP)
STRING * versionlib = NULL;
STRING * entry = NULL;
STRING * builddir = NULL;
+ STRING * dynext_libs = NULL;
PMC * const lib_paths =
VTABLE_get_pmc_keyed_int(interp, interp->iglobals, IGLOBALS_LIB_PATHS);
PMC * const config_hash =
@@ -226,10 +246,12 @@ Parrot_lib_update_paths_from_config_hash(PARROT_INTERP)
STRING * const verkey = CONST_STRING(interp, "versiondir");
STRING * const builddirkey = CONST_STRING(interp, "build_dir");
STRING * const installed = CONST_STRING(interp, "installed");
+ STRING * const dynextkey = CONST_STRING(interp, "dynext_libs");
versionlib = VTABLE_get_string_keyed_str(interp, config_hash, libkey);
entry = VTABLE_get_string_keyed_str(interp, config_hash, verkey);
versionlib = Parrot_str_concat(interp, versionlib, entry);
+ dynext_libs = VTABLE_get_string_keyed_str(interp, config_hash, dynextkey);
if (!VTABLE_get_integer_keyed_str(interp, config_hash, installed))
builddir = VTABLE_get_string_keyed_str(interp,
@@ -283,6 +305,13 @@ Parrot_lib_update_paths_from_config_hash(PARROT_INTERP)
entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/dynext/"));
VTABLE_push_string(interp, paths, entry);
}
+#ifdef WIN32
+ entry = CONST_STRING(interp, "./");
+ VTABLE_push_string(interp, paths, entry);
+#endif
+ if (!STRING_IS_NULL(dynext_libs) && !STRING_IS_EMPTY(dynext_libs)) {
+ add_env_paths(interp, paths, dynext_libs);
+ }
}
@@ -474,6 +503,54 @@ path_concat(PARROT_INTERP, ARGIN(STRING *l_path),
/*
+=item C<static void add_env_paths(PARROT_INTERP, PMC *libpath, const STRING
+*envstr)>
+
+Split the env string into its components and add the entries to the libpath.
+
+=cut
+
+*/
+
+static void
+add_env_paths(PARROT_INTERP, ARGIN(PMC *libpath),
+ ARGIN(const STRING *envstr))
+{
+ ASSERT_ARGS(add_env_paths)
+
+ if (!STRING_IS_NULL(envstr) && !STRING_IS_EMPTY(envstr)) {
+#ifdef WIN32
+ STRING * const env_search_path_sep = CONST_STRING(interp, ";");
+#else
+ STRING * const env_search_path_sep = CONST_STRING(interp, ":");
+#endif
+ INTVAL start = 0;
+ INTVAL index;
+
+ if ((index = STRING_index(interp, envstr, env_search_path_sep, start)) >= 0) {
+ STRING * entry;
+ do {
+ entry = STRING_substr(interp, envstr, start, index - start);
+ if (!STRING_IS_EMPTY(entry)) { /* skip empty, as in ":/path" */
+ VTABLE_push_string(interp, libpath,
+ path_guarantee_trailing_separator(interp, entry));
+ }
+ start = index + 1;
+ } while ((index = STRING_index(interp, envstr, env_search_path_sep, start)) >= 0);
+ entry = STRING_substr(interp, envstr, start, STRING_length(envstr) - start);
+ if (!STRING_IS_EMPTY(entry))
+ VTABLE_push_string(interp, libpath,
+ path_guarantee_trailing_separator(interp, entry));
+ }
+ else {
+ VTABLE_push_string(interp, libpath,
+ path_guarantee_trailing_separator(interp, envstr));
+ }
+ }
+}
+
+/*
+
=item C<static STRING* try_load_path(PARROT_INTERP, STRING* path)>
Attempts to load a file with name C<path>. If the file is successfully located,
View
46 t/library/lib_search_path.t
@@ -8,7 +8,7 @@ use lib qw(lib);
use Test::More;
use Parrot::Config;
use Parrot::Test;
-plan tests => 5;
+plan tests => 7;
=head1 NAME
@@ -28,15 +28,17 @@ Check for proper libpath order.
dynext:
if parrot is installed:
- $ENV{PARROT_LIBRARY}
dynext/
+ $ENV{PARROT_DYNEXT}
$prefix/parrot/$ver/dynext/
+ $Config{dynext_libs}
if not installed:
- $ENV{PARROT_LIBRARY}
dynext/
+ $ENV{PARROT_DYNEXT}
$build_dir/runtime/parrot/dynext
+ $Config{dynext_libs}
library (similar for include):
if parrot is installed:
@@ -56,12 +58,14 @@ LANG does not observe $ENV{PARROT_LIBRARY}
no duplicates
-. at end (not for DYNEXT)
+. at the end, for DYNEXT only on windows
=cut
+my $sep = $^O eq 'MSWin32' ? ';' : ':';
local $ENV{PARROT_LIBRARY} = 'libenvdir';
local $ENV{PARROT_INCLUDE} = 'incenvdir';
+local $ENV{PARROT_DYNEXT} = "/dynenvdir1$sep/dynenvdir2";
my ($builddir, $versiondir, $libdir, $prefix) = @PConfig{qw(build_dir versiondir libdir)};
my $versionlib = $libdir . $versiondir;
@@ -90,12 +94,42 @@ my $code = <<"CODE";
CODE
my $dynext = Parrot::Test::_pir_stdin_output_slurp('', $code);
+my $dynext_libs = $PConfig{dynext_libs};
my $expected =
"dynext/
+/dynenvdir1/
+/dynenvdir2/
+$builddir/runtime/parrot/dynext/
+$versionlib/dynext/
+";
+$expected .= join("\n", split /$sep/, $dynext_libs)."\n" if $dynext_libs;
+$expected .= "./\n" if $^O eq 'MSWin32';
+is ($dynext, $expected, "dynext (multi ENV)");
+
+$ENV{PARROT_DYNEXT} = "/dynenvdir";
+$dynext = Parrot::Test::_pir_stdin_output_slurp('', $code);
+$dynext_libs = $PConfig{dynext_libs};
+$expected =
+"dynext/
+/dynenvdir/
+$builddir/runtime/parrot/dynext/
+$versionlib/dynext/
+";
+$expected .= join("\n", split /$sep/, $dynext_libs)."\n" if $dynext_libs;
+$expected .= "./\n" if $^O eq 'MSWin32';
+is ($dynext, $expected, "dynext (single ENV)");
+
+undef $ENV{PARROT_DYNEXT};
+$dynext = Parrot::Test::_pir_stdin_output_slurp('', $code);
+$dynext_libs = $PConfig{dynext_libs};
+$expected =
+"dynext/
$builddir/runtime/parrot/dynext/
$versionlib/dynext/
";
-is ($dynext, $expected, "dynext");
+$expected .= join("\n", split /$sep/, $dynext_libs)."\n" if $dynext_libs;
+$expected .= "./\n" if $^O eq 'MSWin32';
+is ($dynext, $expected, "dynext (no ENV)");
my $library = $code;
$library =~ s/DYNEXT/LIBRARY/;
@@ -131,7 +165,7 @@ $versionlib/languages/
is ($lang, $expected, "lang");
-pir_output_is( <<'CODE', <<'OUTPUT', ". at end of dynext search path" );
+pir_output_is( <<'CODE', <<'OUTPUT', ". at end of library search path" );
.sub main :main
load_bytecode 't/pir/testlib/loadtest.pbc'
.end

0 comments on commit fa14122

Please sign in to comment.