Missing vcl resource

At one point in the past, I started getting this annoying error message dialog

VCL resource warning dialog on startup

on startup, and OO.o simply shuts itself down after that. It happened whenever I installed the trunk version of ooo-build with ooinstall (with an -l option for linking), or the upstream build with linkoo. These two commands are two, totally separate scripts, but they both create symbolic links to the shared libraries and resources in the installation directory, to their respective location in the build (actually ooinstall makes use of linkoo for the -l functionality). This setting allows a fast iteration of code change, compilation and testing without having to manually swap the shared libraries each time they get modified in the build. But because of this problem I was not able to use linkoo with the upstream build, or ooinstall -l with the trunk ooo-build, and was forced to manually set symlink to the modules I was working on. (Somehow, the 2.2 and 2.1 branches of ooo-build didn’t have this problem.)

But today, after not having been able to use an automatically symlinked installation for a long, long time, I got tired of it and decided to jump into the code, to see what causes this problem.

After a little tracing of the code, I finally found the offending code block (tools/source/rc/resmgr.cxx#244):

void ResMgrContainer::init()
    // get resource path
    std::list< OUString > aDirs;
    sal_Int32 nIndex = 0;
    // 1. relative to current module (<installation>/program/resource)
    OUString libraryFileUrl;
    if( Module::getUrlFromAddress(
            reinterpret_cast< oslGenericFunction >(ResMgrContainer::release),
            libraryFileUrl) )
        nIndex = libraryFileUrl.lastIndexOf( '/' );
    DBG_ASSERT( nIndex > 0, "module resolution failed" );
    if( nIndex > 0 )
        OUStringBuffer aBuf( libraryFileUrl.getLength() + 16 );
        aBuf.append( libraryFileUrl.getStr(), nIndex+1 ); // copy inclusive '/'
        aBuf.appendAscii( "resource" );
        aDirs.push_back( aBuf.makeStringAndClear() );

Here is what the code does. It tries to locate all of the resources (.res) files and put their locations into an internal data structure. To do it, it needs to know where to find the resource files. It cleverly determines the resource file directory by first getting the absolute path of the module where the code resides (libtl680li.so), and move down to the resource file directory from that location. In the normal installation, the modules are located in the [installation root]/program/, and the resources directory is only one level down.

However, when the shared library in question is a symbolic link (symlink) to another file, the code ends up getting the path of the actual file the symlink points to, instead of the path of that symlink (via dladdr call), and this causes the above problem.

There is an easy workaround. Since it’s only the shared library where the ResMgrContainer class is (which is libtl680li.so as mentioned) needs to be the actual file, you can simply delete the symlink that points to libtl680li.so, and put the original file in its place. Then OO.o launches just fine. You can leave all the other symlinked shared libraries alone. The only problem with this workaround is, if you want to hack at the tools code, you would need to manually swap the shared library on each module re-build, but for me, that’s not a major problem (I don’t hack at the tools code).

Cognitive Dissonance

There are certain words I can never type right for the first time. One is ‘formula’. My finger always wants to type it as ‘formular’, thinking that there is a missing ‘r’ at the end. Another one is ‘cvs’. I always end up typing ‘svn’, then backspacing it three times to retype ‘cvs’. However, I have no problem typing ‘git’ (I’m not kidding!).