zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

BashCompletion.cmake (4163B)


      1 # A wrapper around pkg-config-provided and cmake-provided bash completion that
      2 # will have dynamic behavior at INSTALL() time to allow both root-level
      3 # INSTALL() as well as user-level INSTALL().
      4 #
      5 # See also https://github.com/scop/bash-completion
      6 #
      7 # Copyright (c) 2018, Tres Finocchiaro, <tres.finocchiaro@gmail.com>
      8 # Redistribution and use is allowed according to the terms of the BSD license.
      9 # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
     10 #
     11 # Usage:
     12 #    INCLUDE(BashCompletion)
     13 #    BASHCOMP_INSTALL(foo)
     14 #    ... where "foo" is a shell script adjacent to the CMakeLists.txt
     15 #
     16 # How it determines BASHCOMP_PKG_PATH, in order:
     17 #    1. Uses BASHCOMP_PKG_PATH if already set (e.g. -DBASHCOMP_PKG_PATH=...)
     18 #       a. If not, uses pkg-config's PKG_CHECK_MODULES to determine path
     19 #       b. Fallback to cmake's FIND_PACKAGE(bash-completion) path
     20 #       c. Fallback to hard-coded /usr/share/bash-completion/completions
     21 #    2. Final fallback to ${CMAKE_INSTALL_PREFIX}/share/bash-completion/completions if
     22 #       detected path is unwritable.
     23 
     24 # - Windows does not support bash completion
     25 # - macOS support should eventually be added for Homebrew (TODO)
     26 IF(WIN32)
     27 	MESSAGE(STATUS "Bash completion is not supported on this platform.")
     28 ELSEIF(APPLE)
     29 	MESSAGE(STATUS "Bash completion is not yet implemented for this platform.")
     30 ELSE()
     31 	INCLUDE(FindUnixCommands)
     32 	# Honor manual override if provided
     33 	IF(NOT BASHCOMP_PKG_PATH)
     34 		# First, use pkg-config, which is the most reliable
     35 		FIND_PACKAGE(PkgConfig QUIET)
     36 		IF(PKGCONFIG_FOUND)
     37 			PKG_CHECK_MODULES(BASH_COMPLETION bash-completion)
     38 			PKG_GET_VARIABLE(BASHCOMP_PKG_PATH bash-completion completionsdir)
     39 		ELSE()
     40 			# Second, use cmake (preferred but less common)
     41 			FIND_PACKAGE(bash-completion QUIET)
     42 			IF(BASH_COMPLETION_FOUND)
     43 				SET(BASHCOMP_PKG_PATH "${BASH_COMPLETION_COMPLETIONSDIR}")
     44 			ENDIF()
     45 		ENDIF()
     46 
     47 		# Third, use a hard-coded fallback value
     48 		IF("${BASHCOMP_PKG_PATH}" STREQUAL "")
     49 			SET(BASHCOMP_PKG_PATH "/usr/share/bash-completion/completions")
     50 		ENDIF()
     51 	ENDIF()
     52 
     53 	# Always provide a fallback for non-root INSTALL()
     54 	SET(BASHCOMP_USER_PATH "${CMAKE_INSTALL_PREFIX}/share/bash-completion/completions")
     55 
     56 	# Cmake doesn't allow easy use of conditional logic at INSTALL() time
     57 	# this is a problem because ${BASHCOMP_PKG_PATH} may not be writable and we
     58 	# need sane fallback behavior for bundled INSTALL() (e.g. .AppImage, etc).
     59 	#
     60 	# The reason this can't be detected by cmake is that it's fairly common to
     61 	# run "cmake" as a one user (i.e. non-root) and "make install" as another user
     62 	# (i.e. root).
     63 	#
     64 	# - Creates a script called "install_${SCRIPT_NAME}_completion.sh" into the
     65 	#   working binary directory and invokes this script at install.
     66 	# - Script handles INSTALL()-time conditional logic for sane ballback behavior
     67 	#   when ${BASHCOMP_PKG_PATH} is unwritable (i.e. non-root); Something cmake
     68 	#   can't handle on its own at INSTALL() time)
     69 	MACRO(BASHCOMP_INSTALL SCRIPT_NAME)
     70 		# A shell script for wrapping conditionl logic
     71 		SET(BASHCOMP_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/install_${SCRIPT_NAME}_completion.sh")
     72 
     73 		FILE(WRITE ${BASHCOMP_SCRIPT} "\
     74 #!${BASH}\n\
     75 set -e\n\
     76 BASHCOMP_PKG_PATH=\"${BASHCOMP_USER_PATH}\"\n\
     77 if [ -n \"${BASHCOMP_PKG_PATH}\" ]; then\n\
     78   BASHCOMP_PKG_PATH=\"${BASHCOMP_PKG_PATH}\"\n\
     79 fi\n\
     80 echo -e \"\\nInstalling bash completion...\\n\"\n\
     81 mkdir -p \"\${DESTDIR}/$BASHCOMP_PKG_PATH\"\n\
     82 cp \"${CMAKE_CURRENT_BINARY_DIR}/${SCRIPT_NAME}\" \"\${DESTDIR}/$BASHCOMP_PKG_PATH\"\n\
     83 chmod a+r \"\${DESTDIR}/$BASHCOMP_PKG_PATH/${SCRIPT_NAME}\"\n\
     84 echo -e \"Bash completion for ${SCRIPT_NAME} has been installed to \${DESTDIR}/$BASHCOMP_PKG_PATH/${SCRIPT_NAME}\"\n\
     85 ")
     86 		INSTALL(CODE "EXECUTE_PROCESS(COMMAND chmod u+x \"install_${SCRIPT_NAME}_completion.sh\" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} )")
     87 		INSTALL(CODE "EXECUTE_PROCESS(COMMAND \"./install_${SCRIPT_NAME}_completion.sh\" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} )")
     88 
     89     MESSAGE(STATUS "Bash completion script for ${SCRIPT_NAME} will be installed to ${DESTDIR}/${BASHCOMP_PKG_PATH} or fallback to ${BASHCOMP_USER_PATH} if unwritable.")
     90 	ENDMACRO()
     91 ENDIF()
     92