Skip to content

Commit

Permalink
WIP: Finish up install-related documentation (#314)
Browse files Browse the repository at this point in the history
  • Loading branch information
bartlettroscoe committed Apr 29, 2020
1 parent b3e1688 commit 0008a98
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 40 deletions.
3 changes: 1 addition & 2 deletions tribits/core/package_arch/TribitsAddExecutable.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,7 @@ INCLUDE(CMakeParseArguments)
# CMake command ``INSTALL(TARGETS <exeTargetName> ...)`` is added to install
# the built executable into the ``${CMAKE_INSTALL_PREFIX}/bin/`` directory
# (actual install directory path is determined by
# ``${PROJECT_NAME}_INSTALL_RUNTIME_DIR``, see `Setting the install prefix at
# configure time`_) .
# ``${PROJECT_NAME}_INSTALL_RUNTIME_DIR``, see `Setting the install prefix`_).
#
FUNCTION(TRIBITS_ADD_EXECUTABLE EXE_NAME)

Expand Down
11 changes: 5 additions & 6 deletions tribits/core/package_arch/TribitsLibraryMacros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ ENDFUNCTION()
# By default, an install target for the library is created using
# ``INSTALL(TARGETS <libTargetName> ...)`` to install into the directory
# ``${CMAKE_INSTALL_PREFIX}/lib/`` (actual install directory is given by
# ``${PROJECT}_INSTALL_LIB_DIR``, see `Setting the install prefix at configure
# time`_). However, this install target will not get created if
# ``${PROJECT}_INSTALL_LIB_DIR``, see `Setting the install prefix`_).
# However, this install target will not get created if
# `${PROJECT_NAME}_INSTALL_LIBRARIES_AND_HEADERS`_ is ``FASLE`` and
# ``BUILD_SHARD_LIBS=OFF``. But when ``BUILD_SHARD_LIBS=ON``, the install
# target will get added. Also, this install target will *not* get added if
Expand All @@ -430,10 +430,9 @@ ENDFUNCTION()
# `${PROJECT_NAME}_INSTALL_LIBRARIES_AND_HEADERS`_ is ``FASLE``. If this
# install target is added, then the headers get installed into the flat
# directory ``${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}/`` (default is
# ``${CMAKE_INSTALL_PREFIX}/include/``, see `Setting the install prefix at
# configure time`_). If ``HEADERS_INSTALL_SUBDIR`` is set, then the headers
# will be installed under
# ``${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}/<headerssubdir>/``.
# ``${CMAKE_INSTALL_PREFIX}/include/``, see `Setting the install prefix`_).
# If ``HEADERS_INSTALL_SUBDIR`` is set, then the headers will be installed
# under ``${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}/<headerssubdir>/``.
#
# Note that an install target will *not* get created for the headers listed in
# ``NOINSTALLHEADERS``.
Expand Down
63 changes: 37 additions & 26 deletions tribits/doc/build_ref/TribitsBuildReferenceBody.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3079,39 +3079,44 @@ absolute paths, use the data type ``PATH`` as shown above.
Setting install ownership and permissions
-----------------------------------------

By default, when installing with the ``install`` target, any files and
directories created are given the default permissions for the user that runs
the install command (just as if they typed ``mkdir <some-dir>`` or ``touch
<some-fle>``). On most Unix/Linux systems, one can use ``umask`` to set
default permissions and set the default group and the group sticky bit to
control what groups owns created files and directories. However, some
computer systems do not support the group sticky bit and there are cases where
one wants or needs to provide different group ownership and write permissions.

To control what group owns the install-created files and directory and define
the permissions on those, one can set one or more of the following options::
By default, when installing with the ``install`` (or
``install_package_by_package``) target, any files and directories created are
given the default permissions for the user that runs the install command (just
as if they typed ``mkdir <some-dir>`` or ``touch <some-file>``). On most
Unix/Linux systems, one can use ``umask`` to set default permissions and one
can set the default group and the group sticky bit to control what groups owns
the newly created files and directories. However, some computer systems do
not support the group sticky bit and there are cases where one wants or needs
to provide different group ownership and write permissions.

To control what group owns the install-created files and directories related
to ``CMAKE_INSTALL_PREFIX`` and define the permissions on those, one can set
one or more of the following options::

-D <Project>_SET_GROUP_AND_PERMISSIONS_ON_INSTALL_BASE_DIR=<install-base-dir> \
-D <Project>_MAKE_INSTALL_GROUP=[<owning-group>] \
-D <Project>_MAKE_INSTALL_GROUP_READABLE=[TRUE|FALSE] \
-D <Project>_MAKE_INSTALL_GROUP_WRITABLE=[TRUE|FALSE] \
-D <Project>_MAKE_INSTALL_WORLD_READABLE=[TRUE|FALSE] \

This has the impact of both setting the built-in CMake variable
(where ``<Project>_SET_GROUP_AND_PERMISSIONS_ON_INSTALL_BASE_DIR`` must be a
base directory of ``CMAKE_INSTALL_PREFIX``). This has the impact of both
setting the built-in CMake variable
``CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS`` with the correct permissions
according to these and also triggers the automatic running of the recursive
``chgrp`` and ``chmod`` commands starting from the directory
``<install-base-dir>`` on down, after all of the other project files have been
installed. The directory set by
``<Project>_SET_GROUP_AND_PERMISSIONS_ON_INSTALL_BASE_DIR`` must be a base
directory of ``CMAKE_INSTALL_PREFIX`` and that base directory may be created
by the ``install`` command by CMake (as it may not exist before the install).
If ``<Project>_SET_GROUP_AND_PERMISSIONS_ON_INSTALL_BASE_DIR`` is not given,
then it is set internally to the same directory as ``CMAKE_INSTALL_PREFIX``.
``<Project>_SET_GROUP_AND_PERMISSIONS_ON_INSTALL_BASE_DIR`` and those below it
may be created by the ``install`` command by CMake (as it may not exist before
the install). If ``<Project>_SET_GROUP_AND_PERMISSIONS_ON_INSTALL_BASE_DIR``
is not given, then it is set internally to the same directory as
``CMAKE_INSTALL_PREFIX``.

For an example, to configure for an install based on a dated base directory
where a non-default should group own the installation and has group read/write
permissions, and others only have read access, one would configure with::
where a non-default group should own the installation and have group
read/write permissions, and "others" only have read access, one would
configure with::

-D CMAKE_INSTALL_PREFIX=$HOME/2020-04-25/my-proj \
-D <Project>_SET_GROUP_AND_PERMISSIONS_ON_INSTALL_BASE_DIR=$HOME/2020-04-25 \
Expand All @@ -3120,21 +3125,27 @@ permissions, and others only have read access, one would configure with::
-D <Project>_MAKE_INSTALL_WORLD_READABLE=TRUE \

Using these settings, after all of the files and directories have been
installed in the ``install`` or ``install_package_by_package`` targets, the
following commands are run at the very end::
installed using the ``install`` or ``install_package_by_package`` build
targets, the following commands are automatically run at the very end::

chgrp some-other-group $HOME/2020-04-25
chmod g+rwX,o+rX $HOME/2020-04-25
chgrp some-other-group -R $HOME/2020-04-25/my-proj
chmod g+rwX,o+rX -R $HOME/2020-04-25/my-proj

That allows the owning group ``some-other-group`` to later modify or delete
the installation and allows all users to use the installation. (This also
avoids changing the group or permissions for files and directories sister
directories of ``CMAKE_INSTALL_PREFIX``)
the installation and allows all users to use the installation.

NOTES:

* Setting ``<Project>_MAKE_INSTALL_GROUP_WRITABLE=TRUE`` implies
``<Project>_MAKE_INSTALL_GROUP_READABLE=TRUE``.

NOTE: Setting ``<Project>_MAKE_INSTALL_GROUP_WRITABLE=TRUE`` implies
``<Project>_MAKE_INSTALL_GROUP_READABLE=TRUE``.
* Non-recursive ``chgrp`` and ``chmod`` commands are run on the directories
above ``CMAKE_INSTALL_PREFIX``. Recursive ``chgrp`` and ``chmod`` commands
are only run on the base ``CMAKE_INSTALL_PREFIX`` directory itself. (This
avoids touching any files or directories not directly involved in this
install.)


Setting install RPATH
Expand Down
71 changes: 65 additions & 6 deletions tribits/doc/developers_guide/TribitsDevelopersGuide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6519,10 +6519,67 @@ ready to compile code. All of the major variables set as part of this process
are printed to the ``cmake`` stdout when the project is configured.


Installation permsisions
------------------------
Installation considerations
---------------------------

ToDo: Finish this!
For the most part, installation is pretty straightforward with a TriBITS-based
CMake project. TriBITS automatically puts in appropriate default
``install()`` commands to install header files, libraries, executables, and
other commonly installed artifacts (such as TriBITS-autogenerated
``<Package>Config.cmake`` files). And packages can add their own custom
``install()`` commands to install items under ``CMAKE_INSTALL_PREFIX`` (or the
subdirs under ``CMAKE_INSTALL_PREFIX`` mentioned in `Setting the install
prefix`_). However, there are some special situations that need to be
addressed and some tweaks to built-in CMake support that need to be made.

One issue that can occur is that there are cases where a Unix/Linux system is
set up not to honor the group sticky bit and therefore one cannot control what
group owns the created installed files and directories (i.e. the default group
will be used). Also, there are cases were one cannot easily control the
default file or directory creation permissions using ``umask``. And there are
cases where one would like to recursively install a set of directories and
files where some of these files may be scripts that need to have the execute
permission set on them for them to work. The only to flexiable accomplish
that with CMake (if one does not know the exist list of those files or
extensions of those files) is to pass in the ``SOURCE_PERMISSIONS`` option to
the ``install(DIRECTORY ...)`` command. An example of this is shown in:

* ``TribitsExampleProject/packages/with_subpackages/b/CMakeLists.txt``

that has::

INSTALL( DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/stuff"
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/${PACKAGE_NAME}"
USE_SOURCE_PERMISSIONS PATTERN "*~" EXCLUDE )

In this case, CMake will preserve the execute permission on any of the scripts
contained under the ``stuff/`` subdirectory but ``group`` and ``other``
permissions will not be set based on ``umask`` or the default CMake install
permissions. Instead, these permissions are set based on the source directory
permissions (which is often set to ``700`` or ``rwx------``).

To address cases like this, TriBITS can automatically run ``chgrp`` and
``chmod`` on the created files and directories that are created during the
``install`` target as described in `Setting install ownership and
permissions`_. This is completely automatic and requires nothing for the
TriBITS Project developers to do to enable support for this (other than to
note the below warning).

**WARNING**: Do not add any ``install()`` commands after the
`TRIBITS_PROJECT()`_ command completes. Otherwise, any extra files or
directories will not have their group and permissions fixed by these special
TriBITS-added ``chgrp`` and ``chmod`` commands run at install time. Instead,
try to put all ``install()`` commands inside of a package's
`<packageDir>/CMakeLists.txt`_ file. Currently, there really is no good place
to add repo-level or project-level ``install()`` commands. But if one had to
sneak them in, they could add various ``install()`` commands to files like
`<projectDir>/CMakeLists.txt`_ (before the ``TRIBITS_PROJECT_()`` command),
`<repoDir>/cmake/CallbackSetupExtraOptions.cmake`_,
`<projectDir>/cmake/CallbackDefineProjectPackaging.cmake`_ and/or
`<repoDir>/cmake/CallbackDefineRepositoryPackaging.cmake`_. (Note that
install commands from the former two files are run before install commands for
the enabled packages while install commands from the latter two files are run
after.)


RPATH Handling
Expand Down Expand Up @@ -8580,10 +8637,10 @@ These options are described below.

SET(${PROJECT_NAME}_MAKE_INSTALL_WORLD_READABLE_DEFAULT TRUE)

On non-Windoes systems, these set permissions for all files and directories
On non-Windows systems, these set permissions for all files and directories
from the the user-set base directory
``${PROJECT_NAME}_SET_GROUP_AND_PERMISSIONS_ON_INSTALL_BASE_DIR`` on down.
For more details see `Installation permsisions`_.
For more details see `Installation considerations`_.

These defaults can be set in the `<projectDir>/ProjectName.cmake`_ file.

Expand Down Expand Up @@ -9244,7 +9301,9 @@ Below is a snapshot of the output from ``install_devtools.py --help``.

.. _make dashboard: TribitsBuildReference.html#dashboard-submissions

.. _Setting the install prefix at configure time: TribitsBuildReference.html#setting-the-install-prefix-at-configure-time
.. _Setting the install prefix: TribitsBuildReference.html#setting-the-install-prefix

.. _Setting install ownership and permissions: TribitsBuildReference.html#setting-install-ownership-and-permissions

.. _TRIBITS_2ND_CTEST_DROP_SITE: TribitsBuildReference.html#tribits-2nd-ctest-drop-site

Expand Down

0 comments on commit 0008a98

Please sign in to comment.