Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a custom symbolic link to a library at install time with CMake

Under Linux with CMake, I'm building a shared library libIex-2_0.so.10.0.1

ADD_LIBRARY (Iex SHARED
  [*.cpp]
)
SET_TARGET_PROPERTIES(Iex PROPERTIES OUTPUT_NAME "Iex-2_0")

The 10.0.1 version is set with a call to

SET_TARGET_PROPERTIES ( Iex
  PROPERTIES
  VERSION 10.0.1
  SOVERSION 10
)

In the installation folder, these links are created

libIex-2_0.so -> libIex-2_0.so.10
libIex-2_0.so.10 -> libIex-2_0.so.10.0.1
libIex-2_0.so.10.0.1

However, to match previous builds made with another build system, I need to add a legacy symbolic link, stripping the 2_0 suffix :

libIex.so -> libIex-2_0.so.10.0.1

What would be the proper CMake way to create such a link ?

like image 946
Charles Avatar asked Sep 09 '13 21:09

Charles


2 Answers

One way to do it could be using CMake add_custom_command and add_custom_target. In your case it would be something like the following:

 SET( legacy_link   ${CMAKE_INSTALL_PREFIX}/libIex.so)
 SET( legacy_target ${CMAKE_INSTALL_PREFIX}/libIex-2_0.so.10.0.1)
 ADD_CUSTOM_COMMAND( OUTPUT ${legacy_link}
                     COMMAND ln -s ${legacy_target} ${legacy_link}
                     DEPENDS install ${legacy_target} 
                     COMMENT "Generating legacy symbolic link")

 ADD_CUSTOM_TARGET( install_legacy DEPENDS ${legacy_link} )

At this point you should have a target install_legacy in your generated Makefile with the correct dependency to generate libIex.so.

like image 192
Massimiliano Avatar answered Sep 19 '22 19:09

Massimiliano


Another way is to run some install(CODE shell-script). It does correctly attach to the general "make install" target by the way. With better control on the working_directory it is also possible to create relative symlinks easily.

I did also require that make install DESTDIR=/buildroot works and for that it is required to leave $DESTDIR unexpanded until the shell-script is invoked. Along with some magic for portability it looks like this:

get_target_property(libname MyLib OUTPUT_NAME)
get_target_property(libversion MyLib VERSION)
set(lib ${CMAKE_SHARED_LIBRARY_PREFIX})
set(dll ${CMAKE_SHARED_LIBRARY_SUFFIX})
install(CODE "execute_process(
    COMMAND bash -c \"set -e
    cd $DESTDIR/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
    echo -n .. Installing: `pwd`
    ln -sv ${lib}${libname}${dll}.${libversion} ${lib}${libname}${dll}.11
    echo -n .. Installing: `pwd`
    ln -sv ${lib}${libname}${dll}.${libversion} ${lib}${libname}${dll}.12
    \")")

P.S. assuming include ( GNUInstallDirs ) here.

like image 30
Guido U. Draheim Avatar answered Sep 20 '22 19:09

Guido U. Draheim