How to add symbolic links for loadable MODULE like for shared lib?

I’m using cmake-3.16, and for other technical reason, I must use MODULE to make a dynamic loadable module(*.so) in Linux instead of using SHARED.

But with MODULE, cmake does NOT produce target files with name like “libDummy.so.x.x.x”, and automatically create a symbolic link with names like “libDummy.so”.

So I manually use OUTPUT_NAME_RELEASE to declare the target name as following:

add_library( Dummy MODULE Dummy.cpp )
set_target_properties( Dummy PROPERTIES
    PREFIX              ""
    SUFFIX              ""
    OUTPUT_NAME_RELEASE "Dummy.so.${PROJECT_VERSION}"
    OUTPUT_NAME_DEBUG   "Dummy.so.${PROJECT_VERSION}"
)
install( TARGETS Dummy LIBRARY DESTINATION somewhere )

But I don’t know how to add a symbolic link for it. I found the cmake command:

file( CREATE_LINK "libDummy.so.x.x.x" "libDummy.so" RESULT act_result SYMBOLIC )

looks like doing my requirement. But I don’t understand its syntax. I searched in cmake documents, there are very less comments about it.

So my questions are:

  1. How to refer the target name of my module in the command file( CREATE_LINK )?
  2. How to store the symbolic link into the same folder of the module?
  3. How to make the symbolic link with relative path?

Thanks!

MODULE libraries do not have SONAME or SOVERSION components to them, so there’s no reason to make them. Having to use MODULE and yet still wanting SONAME bits is…odd. Can you provide more details about your requirements?

Thanks for you help!

We are developing a daemon service platform and many plugins with it.
These plugins are loadable modules, because we need to restrict them only can be loaded at runtime, instead of be linked.

In the other hand, every modules can stand with multiple version in a same directory, so we have to make them carry version suffix within file names.

We need to maintain a symbolic link to point out the current active version of every modules respectively, and users can select different version by re-create a symbolic link.

Hmm. Is there a reason the version can’t be part of a directory and then the directory be symlinked to select the current version[1]? Alternatively, you might be able to use SUFFIX to add .${version} so that you get ${name}.${version}.so. But that still requires some other mechanism to select a “default” one to load.

[1] This is similar to what macOS frameworks do with Versions/A and a Versions/Current symlink.

If you use SHARED type with defining PREFIX property to an empty string, the produced library cannot be linked in the normal way but, in this case, CMake will manage correctly versioning and symbolic links.

add_library( Dummy SHARED Dummy.cpp )
set_target_properties( Dummy PROPERTIES
    PREFIX         ""
    SOVERSION      "${PROJECT_VERSION}"
)

You will get, on Linux, Dummy.so.x.x.x and the symbolic link Dummy.so -> Dummy.so.x.x.x. So, no longer lib prefix.

Thanks a lot!

But in this way it still can be linked like this:

add_library( Dummy SHARED IMPORTED )
set_property( TARGET Dummy PROPERTY IMPORT_PREFIX "" )
set_property( TARGET Dummy PROPERTY IMPORTED_LOCATION "/path/to/Dummy.so" )

I write a piece of code to make the symblink like this:

file( CREATE_LINK
    "/etc/my-app/modules/Dummy.so.0.5.4"
    "/etc/my-app/modules/Dummy.so"
    RESULT sym_res
    SYMBOLIC )

It works, but with absolute path, a little ugly.

I want to make the symblink with relative path.

Henc my problem has changed to “How to get the installing path of a specific target?”

I know that CMAKE_INSTALL_PREFIX includes the installing path, but it is for entire project.
Here I need the installing path that dedicated for a target(module).

But in this way it still can be linked

This is also true with MODULE type. You are free to specify a different type when you create an imported target.

It is impossible to prevent someone to link against a library when the full pathname is specified rather than -l linker option.

Are you meaning that the functionality of both are same? at least on Linux platform.

If so, why many docs we saw always suggest that we should use “MODULE” instead of “SHARED” to build a dynamic loadable module, especially in CMake’s documents.

What is the difference between these two types in the end? apart from in Mac OS platforms.

They’re both dynamic libraries. SHARED will get a SONAME (on Linux) whereas MODULE will not. A library id is made on macOS for both (but is moot for MODULE as CMake won’t allow linking to them, though the linker itself doesn’t see a difference). MODULE libraries also do not get symlinks made for SOVERSION or SONAME conveniences. CMake will also not allow MODULE targets on the consumed side of a target_link_libraries call. Other than that…pretty much the same.