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