Shipping Your Product as a Library or a Plugin

In some cases, your product might be a library/DLL/Shared Object which is linked into other programs. If these other programs use RLM as well, you will need to do something to avoid name collisions between your copy of RLM and the other program’s copy of RLM (the other program may use a different RLM version, for example). The technique for accomplishing this is a bit different for Windows and Linux systems.


Windows

Create a DLL that contains the code for your product as well as the RLM code. When you create the list of exports from the DLL, don’t include any RLM functions.

If, for any reason, you need to keep your DLL and the RLM DLL separate, you should take these additional steps to avoid collisions with other ISVs’ versions of the RLM DLL which may be present at runtime:

  • Modify the makefile in the platform directory such that the name of the DLL that gets built includes your ISV name. For example, if your ISV name is “xyz”, modify these lines in the makefile:

    DLL = rlm$(VER).dll
    DLLLIB = rlm$(VER).lib

    to read:

    DLL = xyz_rlm$(VER).dll
    DLLLIB = xyz_rlm$(VER).lib
  • Run nmake in the platform directory to build the DLL under the new name

  • Change any code that references the DLL by name to reflect the new name. An example is RLMInterop.cs - the C# interface to RLM.

  • Link your DLL against <new DLL name>.lib

  • Update your installer to include the RLM DLL and install it in the same location as your product’s DLL.

This will ensure that at runtime even if multiple RLM DLLs are present on the machine, your code will invoke the correct RLM DLL.


Linux/Solaris

Create a shared object (.so) that contains the code for your product as well as the RLM code. When you link your shared object, include the following on the command line:

-Wl,–version-script=file

Note

The character after the uppercase W in the command above is a lowercase l, as in “license” If you create the .so file with ld instead of cc, then just use the -versionscript=file option.

On Solaris, replace “-Wl,–version-script=file” with “-D file

file should contain:

{
        global:
                function1;
                function2;
                ...
                functionN;

        local:
                *;
};

function1, function2, etc, are your functions that can be called from outside the shared object.

The advantage of this technique is that all the RLM symbols will be redefined as local symbols in your .so file.

Alternately, you can specify the -Bsymbolic switch to ld, as follows:

ld -share -Bsymbolic your-object-files.o rlm.a

The -Bsymbolic option tells the loader to bind references to the global symbols in the RLM library (and any other global symbols in your object list) to the definitions within your shared object rather than using previous definitions from other shared objects. This works, however, all the RLM objects will remain globals in your .so file.


MAC

On Mac, you create a dynamic library, and use the “exported_symbols_list” linker option to list the global symbols you want to export. From the macOS ld man page:

-exported_symbols_list filename

The specified filename contains a list of global symbol names that will remain as global symbols in the output file. All other global symbols will be treated as if they were marked as __private_extern__ (aka visibility=hidden) and will not be global in the output file. The symbol names listed in filename must be one per line. Leading and trailing white space are not part of the symbol name. Lines starting with # are ignored, as are lines with only white space. Some wildcards (similar to shell file matching) are supported. The * matches zero or more characters. The ? matches one character. [abc] matches one character which must be an ‘a’, ‘b’, or ‘c’. [a-z] matches any single lowercase letter from ‘a’ to ‘z’.