I have a nice little build issue here. Please note this problem 
is NOT unique to Felix (so it's not a bug, but a general design issue).

To run a program fred.flx we will say

        flx fred.flx

Now, flx will load the current installation host toolchain to make fred,
then run flx.

The toolchain is a plugin, which is typically statically linked in, but in 
general
is dynamically loaded and thence the Felix RTL is also dynamically loaded
(at least at the moment). We could even run flx as a dynamic program with

        flx_run flx.so ....

So, when flx itself loads a plugin and the RTL it needs the (DY)LD_LIBRARY_PATH
set to point to the required location, typically

        $FLX_INSTALL_DIR/host/lib/rtl

Now there's a problem, if the target program "fred" is to run in a different 
environment.
If we say, for example:

        LD_LIBRARY_PATH=build/release/host/lib/rtl flx --test=build/release 
--target=other fred.flx

then flx itself is going to run the fred program with

        LD_LIBRARY_PATH=build/release/other/lib/rtl:$LD_LIBRARY_PATH

This is all well and good. If everything is OK, it will work, because the other 
library
will be searched when running fred, before the host library.

As an example suppose flx is built 64 bit, but we want to run a 32 bit program.
So host is a 64 bit setup, but other is a 32 bit setup. Another example is 
running
a Windows program under Windows, but where the host building environment
is actually Cygwin.

The problem is, if some plugin is not found, the next entry on the 
LD_LIBRARY_PATH
is searched and if it's there we may silently get a host version of a plugin
instead of the required target other. And, the plugin may load the other version
of the RTL instead of the matching host one.

So really, when we run fred it should be with the original LD_LIBRARY_PATH
augmented with other/lib/rtl, and **without** host/lib/rtl in the path.

Unfortunately there is NO WAY that flx can do this, because it can only see the 
LD_LIBRARY_PATH
that is set when it is invoked, which may be augmented by the host. Note it may 
not be!
After all the client may, for example, pre-load the RTL with ldconfig, which 
means it doesn't
need to be in the LD_LIBRARY_PATH.

[In that case, there's no way to actually stop the fallback to the wrong 
library,
so if you like to cross compiled just don't do it!]

Of course it is trivial to do this with a script:

        OLD_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
        LD_LIBRARY_PATH=host flx fred

and have flx invoke fred by reading OLD_LD_LIBRARY_PATH and augmenting that.

For a normal host build, we can arrange to statically link the default toolchain
plugin, in fact, we already do just that (except we link all 4 of them).
But that doesn't solve the problem for a foreign plugin. Even if the build 
system
is extended to statically link some foreign plugins (fairly easy to do), it 
doesn't
help if you write another one AFTERWARDS.

Another solution is to statically link the plugins. By that I mean to link the 
RTL
into the plugins (the plugin is still a shared library, but it doesn't have
load time dependencies on the RTL).

Another solution, as always in computer science, is to add another level
of indirection. In other words, a thunk program that runs flx. THAT program 
can set the library path first, and set a different path to run the executable.

It's also possible on some platforms, but extremely ugly and bad, to link the 
whole
RTL into the executable with its symbol table, and make plugins link to that
(instead of linking to separate RTL libraries at load time). Some programs
in common use, such as Python on some Linux distros (like Ubuntu) do this.
It is utterly wrong. It means the CPython extensions bind to the executable,
but it makes it hard if not impossible to make a CPython module link
to another program that doesn't commit this ugly sin. In fact Felix can
generate Python modules, but they cannot link on Ubuntu with the usual
Python install. It works on OSX because the Apple Python package
uses frameworks instead so the Python interpreter is what it should
be: a stub that does nothing except call the interpreter located in a library.
So on OSX, any C program can not only run Python interpreter but it
can use a CPython module directly.

Unfortunately CPython modules have to be linked "sans Python run time"
and bind to the executable or they have to be linked against the Python
run time library, but it can't necessarily be both (linker dependent if you can
have a go at finding the library in the executable, and if you can't find it
load it).

We can't afford to fall into this trap (I tried to explain but the Python gurus
know everything)

In general dynamic linkage is a mess. It will never be robust, it cannot be 
sorted
out, but we cannot do without it either. Apple's solution is actually the best, 
but it
is also not perfect. Apple binds stuff at link time to a fixed library by an 
absolute
pathname so no library path is required. you can override this with a 
DYLD_LIBRARY_PATH.
This is what Felix does on OSX. To avoid this it would HAVE to build libraries 
one
at a time and install them BEFORE building any dependent code, so that the 
absolute
address of the depended on libraries was already correct. But Felix builds 
everything
in one place and then installs the lot. Very confusing if you forget the 
DYLD_LIBRARY_PATH
and you link against your experimental development code!


--
john skaller
skal...@users.sourceforge.net
http://felix-lang.org




------------------------------------------------------------------------------
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to