llv8call on Mac OS X - 2nd try - macos

I didn't give a lot of info in my last question.
I've built llv8call from http://code.google.com/p/llv8call/, v0.4. I've gotten the known dependencies installed, being libxml-2.0 and libreadline. My dev system is Mac OS X 10.5. llv8call is built with Scons.
When I attempt to run llv8call via ./llv8call, I get this error:
library loading error: org.coderepos.env is not found in : (loadBinary)
I am not sure how to troubleshoot this error. The author hasn't responded to me yet. I need some tips on how to troubleshoot this more than an explicit answer, though if someone has one it's very welcome.
The files are installed to /usr/local/llv8call. There is a directory structure under llv8call/lib/llv8call/org/coderepos but it doesn't contain an "env" directory. My first guess is that whatever library its looking for at org.coderepos.env is supposed to be in this path, but "env" doesn't exist. If this sounds reasonable, it might be a place that I should start looking at but I need confirmation.

Your intuition seems right. Doing a grep:
grep -r "org.coderepos" *|less
I see it checks for many "libraries" under org.coderepos. Furthermore, in src/main.cc in the preload_builtin_classes function, we see:
Handle<Value> args[1];
args[0] = String::New("org.coderepos.fs");
loadBinary->Call(v8ext, 1, args);
args[0] = String::New("org.coderepos.env");
loadBinary->Call(v8ext, 1, args);
if (try_catch.HasCaught()) {
String::Utf8Value error(try_catch.Exception());
fprintf(stderr, "library loading error: %s\n", *error);
exit(2);
}
That, my friend, is your smoking gun.

It is looking for a library called env (i.e., libenv.so) in the directory /org/coderepos.
Either make /org/coderepos and copy the libraries into it, or ask your dynamic linker to look for /org/coderepos content elsewhere.

I fixed this by doing the following from the top-level directory of my llv8call source directory (after running scons to build everything):
mkdir -p out/lib/llv8call/org/coderepos
find ext -name \*.dylib -exec cp {} out/lib/llv8call/org/coderepos \;
"dtruss -f test.sh" was helpful in finding where v8 was looking for the libs.

Related

autoconf: how do I substitute the library prefix?

CLISP's interface to PARI is configured with the configure.in containing AC_LIB_LINKFLAGS([pari]) from lib-link.m4.
The build process also requires the Makefile to know where the datadir of PARI is located. To this end, Makefile.in has
prefix = #LIBPARI_PREFIX#
DATADIR = #datadir#
and expects to find $(DATADIR)/pari/pari.desc (normally
/usr/share/pari/pari.desc or /usr/local/share/pari/pari.desc).
This seems to work on Mac OS X where PARI is installed by homebrew in /usr/local (and LIBPARI_PREFIX=/usr/local), but not on Ubuntu, where PARI is in /usr, and LIBPARI_PREFIX is empty.
How do I insert the location of the PARI's datadir into the Makefile?
PS. I also asked this on the autoconf mailing list.
PPS. In response to #BrunoHaible's suggestion, here is the meager attempt at debugging on Linux (where LIBPARI_PREFIX is empty).
$ bash -x configure 2>&1 | grep found_dir
+ found_dir=
+ eval ac_val=$found_dir
+ eval ac_val=$found_dir
You are trying to use $(prefix) in an unintended way. In an Autotools-based build system, the $(prefix) represents a prefix to the target installation location of the software you're building. By setting it in your Makefile.in, you are overriding the prefix that configure will try to assign. However, since you appear not to have any installation targets anyway, at least at that level, that's probably more an issue of poor form than a cause for malfunction.
How do I insert the location of the PARI's datadir into the Makefile?
I'd recommend computing or discovering the needed directory in your configure script, and exporting it to the generated Makefile via its own output variable. Let's take the second part first, since it's simple. In configure.in, having in some manner located the wanted data directory and assigned it to a variable
DATADIR=...
, you would make an output variable of that via the AC_SUBST macro:
AC_SUBST([DATADIR])
Since you are using only Autoconf, not Automake, you would then manually receive that into your Makefile by changing the assignment in your Makefile.in:
DATDIR = #DATADIR#
Now, as for locating the data directory in the first place, you have to know what you're trying to implement before you can implement it. From your question and followup comments, it seems to me that you want this:
Use a data directory explicitly specified by the user if there is one. Otherwise,
look for a data directory relative to the location of the shared library. If it's not found there then
(optional) look under the prefix specified to configure, or specifically in the specified datadir (both of which may come from the top-level configure). Finally, if it still has not been found then
look in some standard locations.
To create a configure option by which the user can specify a custom data directory, you would probably use the AC_ARG_WITH macro, maybe like this:
AC_ARG_WITH([pari-datadir], [AS_HELP_STRING([--with-pari-datadir],
[explicitly specifies the PARI data directory])],
[], [with_pari_datadir=''])
Thanks to #BrunoHaible, we see that although the Gnulib manual does not document it, the macro's internal documentation specifies that if AC_LIB_LINKFLAGS locates libpari then it will set LIBPARI_PREFIX to the library directory prefix. You find that that does work when the --with-libpari option is used to give it an alternative location to search, so I suggest working with that. You certainly can try to debug AC_LIB_LINKFLAGS to make it set LIBPARI_PREFIX in all cases in which the lib is found, but if you don't want to go to that effort then you can work around it (see below).
Although the default or specified installation prefix is accessible in configure as $prefix, I would suggest instead going to the specified $datadir. That is slightly tricky, however, because by default it refers to the prefix indirectly. Thus, you might do this:
eval "datadir_expanded=${datadir}"
Finally, you might hardcode a set of prefixes such as /usr and /usr/local.
Following on from all the foregoing, then, your configure.in might do something like this:
DATADIR=
for d in \
${with_pari_datadir} \
${LIBPARI_PREFIX:+${LIBPARI_PREFIX}/share/pari} \
${datadir_expanded}/pari \
/usr/local/share/pari \
/usr/share/pari
do
AS_IF([test -r "$[]d/pari.desc"], [DATADIR="$[]d"; break])
done
AS_IF([test x = "x$DATADIR"], [AC_MSG_ERROR(["Could not identify PARI data directory"])])
AC_SUBST([DATADIR])
Instead of guessing the location of datadir, why don't you ask PARI/GP where its datadir is located? Namely,
$ echo "default(datadir)" | gp -qf
"/usr/share/pari"
does the trick.

automake: how set path to linker script?

I've just set up a cross-helloworld automake project (for stm32f4-discovery). There I have a custom discovery.ld scrpt. I put a line in my Makefile.amAM_LDFLAGS = -T discovery.ld. The problem starts when I run confgure from a different folder (e.g. /path/to/source/build) to the one in which the script is situated (/path/to/source). Effectively, being in /path/to/source/build directory, make runs gcc -T discovery.ld ... and fails to find the script because it's in /path/to/source directory and it's not included in the search path list.
-L/path/to/source or -L.. would solve the problem but I don't want to hardcode things.
Maybe there a autoconf/automake variable exists which points to the folder where configure script (and also my discovery.ld) are situated so that I could use it in my Makefile.am?
I'd be glad to any advice.
Many thanks to William Pursell:
AM_LDFLAGS = -T $(top_srcdir)/path/to/discovery.ld

Can't load oracle.so

I am getting this exception:
Can't load '/usr/perl/lib/site_perl/5.8/x86_64-linux/auto/DBD/Oracle/Oracle.so' for module DBD::Oracle: libclntsh.so.8.0: cannot open shared object file:
No such file or directory at
/.../perl/lib/5.8/x86_64-linux/DynaLoader.pm line 169
If I do ls -ltr /.../perl/lib/site_perl/5.8/x86_64-linux/auto/DBD/Oracle/Oracle.so I see that the file is there. The process I am running also sets LD_LIBRARY_PATH before attempting to connect. A build and deploy on another machine doesn't produce the same error and runs fine. Running uname -sm gives Linux x86_64 on both machines. Is there something else that could cause this error?
Another solution:
Just pass your Oracle path variables before you run any scripts:
Like for perl you can do add below in beginning of your script:
BEGIN {
my $ORACLE_HOME = "/usr/lib/oracle/11.2/client64";
my $LD_LIBRARY_PATH = "$ORACLE_HOME/lib";
if ($ENV{ORACLE_HOME} ne $ORACLE_HOME
|| $ENV{LD_LIBRARY_PATH} ne $LD_LIBRARY_PATH
) {
$ENV{ORACLE_HOME} = "/usr/lib/oracle/11.2/client64";
$ENV{LD_LIBRARY_PATH} = "$ORACLE_HOME/lib";
exec { $^X } $^X, $0, #ARGV;
}
}
It looks like DBD::Oracle's Oracle.so is trying to open libclntsh.so.8.0 and can't find it. So you need to find out if that version of the shared library is installed.
Perform the following command:
$ locate libclntsh.so
You should get a list of files beginning with libclntsh.so. If you are lucky , libclntsh.so.8.0 will be among the results, and then you'll need to make sure that the directory that it lives in is on you load path. For instance my server has:
$ locate libclntsh.so
/home/oracle/11.2/lib/libclntsh.so
/home/oracle/11.2/lib/libclntsh.so.10.1
/home/oracle/11.2/lib/libclntsh.so.11.1
If locate fails completely, you can build the database using updatedb or you can try using find:
find / -name 'libclntsh.so*' -print
Use a pager or redirect stderr to a file because you might end up dealing with a lot of error messages from find, which is okay, but using less will allow you to just refresh the screen to see find's output.

gcov can't find a file. Mac OSX

I have a problem with invoking gcov, it keeps returning - No such file or directory.
When I call
localhost:R-3.0.1 romantsegelskyi$ gcov src/main/eval.c
eval.c: No such file or directory
However file itself and information needed for gcov exists.
localhost:R-3.0.1 romantsegelskyi$ ls src/main/eval*
src/main/eval.c src/main/eval.d src/main/eval.gcda src/main/eval.gcno src/main/eval.o
I have tried specifying --object-directory but still no luck
localhost:R-3.0.1 romantsegelskyi$ gcov src/main/eval.c --object-directory=./src/main
eval.c: No such file or directory
Strangest thing is that it is only the case on OSX, on Linux everything works fine as intended. Any ideas?
Same behavior !! And more strange : I get the result (the .gcov file), following this mesg !! Perhaps, you have the result too ?
There two aspects in the problem :
gcov manual said that gcov should execute by default in the directory where the object file and the gcov data files are. The first and simplest working solution is : go in the appropriate directory and execute gcov cd src/main; gcov eval.c
why the --object-directory=... arg seems not working ? Because the expected value is a directory name and in the example given, it is a file name. So you should write --object-directory=src/main (this work too)
or --object-file=src/main/eval.c (according to the doc. I haven't tried this !)

Intltool with an autoconf-generated .desktop file

In the Emperor project, I'm having some issues getting intltool to work when doing an out-of-tree build. When running make check out-of-tree, which is one of the things make distcheck does, intltool fails thus:
INTLTOOL_EXTRACT="/usr/bin/intltool-extract" XGETTEXT="/usr/bin/xgettext" srcdir=../../po /usr/bin/intltool-update --gettext-package emperor --pot
can't open ../../po/../data/emperor.desktop.in: No such file or directory at /usr/bin/intltool-extract line 212.
intltool is looking for emperor.desktop.in, which is listed in po/POTFILES.in, in the source tree. However, emperor.desktop.in is generated by the configure script from a file called emperor.desktop.in.in, in order to insert the installed executable path as configured by the user, and lands in the build tree.
These are the relevant bootstrap.sh lines:
echo +++ Running intltoolize ... &&
intltoolize --force --copy &&
cat >>po/Makefile.in.in <<EOF
../data/_column_names.h:
cd ../data && \$(MAKE) _column_names.h
EOF
The setup code in configure.ac:
IT_PROG_INTLTOOL([0.35.0])
GETTEXT_PACKAGE=emperor
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$GETTEXT_PACKAGE"],
[The domain to use with gettext])
AM_GLIB_GNU_GETTEXT
data/emperor.desktop.in is listed in AC_CONFIG_FILES.
data/Makefile.am contains these lines:
desktopdir = $(datadir)/applications
desktop_in_files = emperor.desktop.in
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
#INTLTOOL_DESKTOP_RULE#
and po/POTFILES.in contains the line
data/emperor.desktop.in
You can review all the details in the public git repository if you wish.
Can I somehow tell intltool that this file will be located in the build tree, not in the source tree? Otherwise, my options appear to be to break make distcheck (not a great option), or to ship a desktop file that doesn't include the full path and assumes that the executable is installed in the PATH. (just as messy, IMHO) - Any other options?
In your source code you have emperor.desktop.in.in, which does not seem to be in any rule as a dependency. That file has to be converted first to emperor.desktop.in and later to emperor.desktop, which does not seem to be the case in your data/Makefile.am.
desktopdir = $(datadir)/applications
desktop_in_in_files = emperor.desktop.in.in
desktop_in_files = $(desktop_in_in_files:.desktop.in.in=.desktop.in)
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
#INTLTOOL_DESKTOP_RULE#
[...]
EXTRA_DIST = \
$(desktop_in_in_files) \
[...]
$(desktop_in_in_files) contains $(desktop_in_in_files), and Makefile will know how to deal with that.
Some further digging has brought me believe that the answer is: intltool does not support source files that aren't source files in the project. Ergo, any additional processing must be done after intltool is through
Intltool requires the lines in POTFILES to be relative to the (build-time) working directory. The file POTFILES is generated by the configure script from POTFILES.in with a simple sed script defined in the IT_PO_SUBDIR autoconf macro (called by IT_PROG_INTLTOOL) that simply prepends the relative location of the top-level source directory to the paths. Alas, modifying POTFILES does not help: the intltool-extract script does everything it can to get the source directory right. I don't believe files that are sometimes inside and sometimes outside the source tree can be supported without modifying intltool itself.

Resources