diff --git a/CMakeLists.txt b/CMakeLists.txt index 72f8bda3a..81b1e47a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ add_subdirectory(plugins) # must precede webgui add_subdirectory(webgui) add_subdirectory(webgui-new) add_subdirectory(webserver) +add_subdirectory(packaging) # Install java libraries install(DIRECTORY diff --git a/Config.cmake b/Config.cmake index 1032ce379..555b02204 100644 --- a/Config.cmake +++ b/Config.cmake @@ -57,6 +57,9 @@ set(INSTALL_BIN_DIR "bin") set(DATABASE sqlite CACHE STRING "Database type") string(TOUPPER ${DATABASE} DATABASE_U) +# Installation directory for dependencies +set(INSTALL_DEPS_DIR_NAME "deps") + # Set up the dynamic libraries' runtime path to the install folder set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) @@ -69,7 +72,9 @@ string(CONCAT CMAKE_INSTALL_RPATH ";../${INSTALL_LIB_DIR_NAME}/${INSTALL_SERVICE_DIR_NAME}" ";$ORIGIN/../${INSTALL_LIB_DIR_NAME}/${INSTALL_SERVICE_DIR_NAME}" ";../${INSTALL_LIB_DIR_NAME}/${INSTALL_AUTH_DIR_NAME}" - ";$ORIGIN/../${INSTALL_LIB_DIR_NAME}/${INSTALL_AUTH_DIR_NAME}") + ";$ORIGIN/../${INSTALL_LIB_DIR_NAME}/${INSTALL_AUTH_DIR_NAME}" + ";../${INSTALL_LIB_DIR_NAME}/${INSTALL_DEPS_DIR_NAME}" + ";$ORIGIN/../${INSTALL_LIB_DIR_NAME}/${INSTALL_DEPS_DIR_NAME}") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # Odb commands diff --git a/doc/deps.md b/doc/deps.md index 221e795fb..796b9d29f 100644 --- a/doc/deps.md +++ b/doc/deps.md @@ -297,3 +297,4 @@ relevant during compilation. | `CODECOMPASS_LINKER` | The path of the linker, if the system's default linker is to be overridden. | | `WITH_PLUGIN`/`WITHOUT_PLUGIN` | The names of the plugins to be built/skipped at build. Possible values are **cpp**, **cpp_reparse**, **dummy**, **git**, **metrics**, **search**. The `metrics` and `search` plugins are fundamental, they will be compiled even if not included. `WITH_PLUGIN` **cannot** be used together with `WITHOUT_PLUGIN`. Example: `-DWITH_PLUGIN="cpp;git"` This will compile the cpp, git, metrics and search plugins. | | `WITH_AUTH` | The names of the authentication plugins to be compiled. Possible values are **plain** and **ldap**. `plain` **cannot** be skipped. Example: `-DWITH_AUTH="plain;ldap"`| +| `INSTALL_RUNTIME_DEPENDENCIES` | If enabled, the required shared objects will be copied to `${CMAKE_INSTALL_PREFIX}/lib/deps/`. Optional, disabled by default. | diff --git a/doc/packaging.md b/doc/packaging.md new file mode 100644 index 000000000..2dbc69b1e --- /dev/null +++ b/doc/packaging.md @@ -0,0 +1,74 @@ +# `.deb` package (For Debian/Ubuntu systems) + +## Installing a CodeCompass `.deb` package +Before installing a package, verify its checksum: +``` +sha256sum codecompass.deb +``` + +### Installing a package +``` +sudo dpkg -i codecompass.deb +``` + +### Removing package +``` +sudo apt remove codecompass +``` + +## Package structure +When a user installs a CodeCompass deb package, all the files will be placed under `/usr/share/codecompass/`. +A few symlinks are created for the CodeCompass commands: +``` +/usr/bin/CodeCompass_logger -> /usr/share/codecompass/bin/CodeCompass_logger +/usr/bin/CodeCompass_parser -> /usr/share/codecompass/bin/CodeCompass_parser +/usr/bin/CodeCompass_webserver -> /usr/share/codecompass/bin/CodeCompass_webserver +``` + +Moreover, CodeCompass requires some dependencies which are no longer available in standard repositories such as `ODB`. +In order to resolve this, the runtime dependencies will be included in the deb package as shared objects. These dependencies will be installed under `/lib/deps/`. + +Finally, a deb package is created by making a copy of the entire ``. + +## Building a `.deb` package +First, we need to build CodeCompass. + +Create a build folder: +``` +mkdir build +cd build +``` + +To enable packaging, run CMake with `-DENABLE_PACKAGING=1`: +``` +cmake .. \ + -DCMAKE_INSTALL_PREFIX= \ + -DDATABASE= \ + -DCMAKE_BUILD_TYPE= \ + -DLLVM_DIR=/usr/lib/llvm-11/cmake \ + -DClang_DIR=/usr/lib/cmake/clang-11 \ + -DENABLE_PACKAGING=1 +``` + +Build and install CodeCompass: +``` +make -j $(nproc) +make install +``` + +Build the deb package: +``` +make deb_package +``` + +The built package will be located in `build/packaging/`. + +## Build options +The built package can be customized by using CMake variables. + +| Variable | Meaning | +| -------------------- | ---------------------------------------- | +| `PACKAGE_FILE_NAME` | File name of the resulting `.deb` package. Standard package notation: `_-.deb`. If not specified, the package will be named `codecompass-dev.deb`. | +| `PACKAGE_VERSION` | Version of the package for the manifest file. If not specified, version `1.0` will be used. | +| `PACKAGE_DEPENDS` | List of package dependencies. Example: `graphviz, libcairo2 (>= 1.6.0), xdg-utils`. If not specified, the package will have no dependencies. | + diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt new file mode 100644 index 000000000..a832c68a3 --- /dev/null +++ b/packaging/CMakeLists.txt @@ -0,0 +1,50 @@ +# Install shared objects to $CMAKE_INSTALL_PREFIX/lib/deps/ +if(INSTALL_RUNTIME_DEPENDENCIES OR ENABLE_PACKAGING) + install(TARGETS CodeCompass_parser CodeCompass_webserver RUNTIME_DEPENDENCIES LIBRARY DESTINATION "${INSTALL_LIB_DIR}/${INSTALL_DEPS_DIR_NAME}") +endif() + +if(NOT ENABLE_PACKAGING) + return() +endif() + +if(NOT PACKAGE_FILE_NAME) + set(PACKAGE_FILE_NAME "codecompass-dev") +endif() + +if(NOT PACKAGE_VERSION) + set(PACKAGE_VERSION "1.0") +endif() + +set(PACKAGE_DIR "${PACKAGE_FILE_NAME}") + +add_custom_target( + deb_package + + COMMAND mkdir -p ${PACKAGE_DIR}/DEBIAN + COMMAND mkdir -p ${PACKAGE_DIR}/usr/share/codecompass + + COMMAND echo "Adding CodeCompass installation ..." + COMMAND cp -r ${CMAKE_INSTALL_PREFIX}/* ${PACKAGE_DIR}/usr/share/codecompass/ + + COMMAND echo "Removing webgui-new sources ..." + COMMAND rm -rf ${PACKAGE_DIR}/usr/share/codecompass/share/codecompass/webgui-new/app/ + + COMMAND cp ${CMAKE_SOURCE_DIR}/packaging/deb/postinst ${PACKAGE_DIR}/DEBIAN/postinst + COMMAND chmod +x ${PACKAGE_DIR}/DEBIAN/postinst + + COMMAND echo "---------- postinst file ----------" + COMMAND cat ${PACKAGE_DIR}/DEBIAN/postinst + COMMAND echo "-----------------------------------" + + COMMAND cp ${CMAKE_SOURCE_DIR}/packaging/deb/control ${PACKAGE_DIR}/DEBIAN/control + COMMAND sed -i "s/\%PACKAGE_VERSION\%/${PACKAGE_VERSION}/" ${PACKAGE_DIR}/DEBIAN/control + COMMAND sed -i "s/\%PACKAGE_DEPENDS\%/${PACKAGE_DEPENDS}/" ${PACKAGE_DIR}/DEBIAN/control + + COMMAND echo "---------- Manifest file ----------" + COMMAND cat ${PACKAGE_DIR}/DEBIAN/control + COMMAND echo "-----------------------------------" + + COMMAND echo "Building package ${PACKAGE_FILE_NAME} ..." + COMMAND dpkg-deb --build ${PACKAGE_DIR} + COMMAND echo "Done!" +) diff --git a/packaging/deb/control b/packaging/deb/control new file mode 100644 index 000000000..0012c77d8 --- /dev/null +++ b/packaging/deb/control @@ -0,0 +1,10 @@ +Package: codecompass +Version: %PACKAGE_VERSION% +Section: devel +Priority: optional +Architecture: amd64 +Depends: %PACKAGE_DEPENDS% +Maintainer: CodeCompass Developers +Homepage: https://github.com/Ericsson/CodeCompass/ +Description: CodeCompass + CodeCompass is a pluginable code comprehension tool. diff --git a/packaging/deb/postinst b/packaging/deb/postinst new file mode 100644 index 000000000..ea3ffcdc4 --- /dev/null +++ b/packaging/deb/postinst @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +# Symlink CodeCompass commands to /usr/bin/ +rm -f /usr/bin/CodeCompass_logger +rm -f /usr/bin/CodeCompass_parser +rm -f /usr/bin/CodeCompass_webserver + +ln -s /usr/share/codecompass/bin/CodeCompass_logger /usr/bin/CodeCompass_logger +ln -s /usr/share/codecompass/bin/CodeCompass_parser /usr/bin/CodeCompass_parser +ln -s /usr/share/codecompass/bin/CodeCompass_webserver /usr/bin/CodeCompass_webserver