bashcmakegnu

How to get the name of GNU install directories outside of CMake or make?


I'm using CMake to install software as defined by GNUInstallDirs which in turn are supposed to follow these standards.

It turns out that these are not entirely uniform across distributions however - libdir becomes lib under ubuntu whereas under alpine it resolves to lib64.

I need to reference these directories outside of CMake in a portable manner - specifically I'm adding a path containing libdir to $PYTHONPATH in a bash script.

How can I find the actual directory name that libdir is resolving to on the current system within bash?


Solution

  • Criteria using which the module GNUInstallDirs chooses between lib and lib64 are described in the module itself:

      # Override this default 'lib' with 'lib64' iff:
      #  - we are on Linux system but NOT cross-compiling
      #  - we are NOT on debian
      #  - we are on a 64 bits system
      # reason is: amd64 ABI: https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI
      # For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if
      # CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu"
      # and CMAKE_INSTALL_PREFIX is "/usr"
      # See http://wiki.debian.org/Multiarch
    

    In a simple form, your Python script could check:

    1. Whether it runs on 64-bit Linux.
    2. Whether it runs on Debian-based OSes.

    If the first check is true but the second is false, then libdir is lib64/. Otherwise libdir is lib/.

    Alternative. Searching for the library

    Your script could check whether lib/ or lib64/ contains a specific library, and for $PYTHONPATH chose the directory which actually contains a library.

    This approach has an advantage, that it is safe against (future) changing rules in GNUInstallDirs module for select between lib/ and lib64/.

    Alternative. Shipping your installation with an information about installing dirs

    When install your project, you could also create a file which contains value of CMAKE_INSTALL_FULL_LIBDIR variable, so this value could be extracted by your Python script. As for the file which contains this information, it could be stored under predefined directory: e.g. datarootdir is always a share/.

    This approach has an advantage, that it works even when the value for libdir differs from both lib/ and lib64/.