diff --git a/.github/workflows/deb.yml b/.github/workflows/deb.yml new file mode 100644 index 000000000..1d17afc52 --- /dev/null +++ b/.github/workflows/deb.yml @@ -0,0 +1,76 @@ +name: Build Debian package + +on: + push: + branches: + - main + - dev + tags: + - 'v*' + pull_request: + +jobs: + build-deb: + runs-on: ubuntu-latest + container: + image: debian:trixie + permissions: + contents: write # needed to attach the .deb to a release on tag builds + + steps: + - name: Install base tooling + run: | + apt-get update + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + git ca-certificates build-essential devscripts equivs lintian + + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Install build dependencies from debian/control + run: | + mk-build-deps --install --remove \ + --tool 'apt-get -y --no-install-recommends' debian/control + + - name: Build the package + run: dpkg-buildpackage -us -uc -b + + - name: Run lintian (informational) + run: lintian ../*.deb || true + + - name: Compute artifact slug + id: slug + run: | + # github.ref_name contains a slash on pull_request events (e.g. + # "4/merge") and for branches like "feature/x"; upload-artifact + # rejects "/" in names. Replace it. Note the default shell here is + # POSIX sh, so use tr rather than bash parameter expansion. + slug="$(printf '%s' "$GITHUB_REF_NAME" | tr '/' '-')" + echo "value=${slug}-${GITHUB_SHA}" >> "$GITHUB_OUTPUT" + + - name: Collect artifacts + run: | + mkdir -p dist + mv ../*.deb dist/ + ls -l dist/ + + - name: Upload .deb artifact + uses: actions/upload-artifact@v6 + with: + name: numbatui-deb-${{ steps.slug.outputs.value }} + path: dist/numbatui_*_amd64.deb + if-no-files-found: error + + - name: Upload debug symbols + uses: actions/upload-artifact@v6 + with: + name: numbatui-dbgsym-${{ steps.slug.outputs.value }} + path: dist/numbatui-dbgsym_*_amd64.deb + if-no-files-found: warn + retention-days: 7 + + - name: Attach .deb to release + if: startsWith(github.ref, 'refs/tags/v') + uses: softprops/action-gh-release@v3 + with: + files: dist/numbatui_*_amd64.deb diff --git a/CMakeLists.txt b/CMakeLists.txt index dbb121a0b..ab416b848 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -843,3 +843,8 @@ elseif(WIN32) endif() endforeach() endif () + + +# Installation rules (FHS layout) for building distribution packages such as +# Debian .deb. Included last so the application/indexer targets already exist. +include(cmake/install.cmake) diff --git a/README.md b/README.md index af76854b9..d80b24c8a 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,45 @@ forwarding required, unlike the Docker image documented above. Note: This build purposely disables C++, Python language indexation features. They shall be re-enabled in future releases. +### Debian package (.deb) + +On Debian/Ubuntu, NumbatUI can be installed as a native `.deb` package. This +installs the GUI and indexer to `/usr/bin`, the runtime data to +`/usr/share/numbatui`, and registers the desktop entry, MIME association +(`*.srctrlprj`) and application icons. + +#### Install a prebuilt package + +Every push to the `main` and `dev` branches builds a `.deb` in CI. Download it +from the **Actions** tab: open the latest *Build Debian package* run and grab +the `numbatui-deb--` artifact (tagged `v*` releases also attach the +`.deb` to the GitHub release). Then: + +```bash +sudo apt install ./numbatui_*_amd64.deb +``` + +`apt` pulls in the required Qt 6 and Boost runtime libraries automatically. + +#### Build the package yourself + +From a checkout of the repository: + +```bash +# one-off: install the build dependencies declared in debian/control +sudo apt build-dep . +# or, without a deb-src entry: +# sudo apt install devscripts equivs && sudo mk-build-deps -i debian/control + +# build the binary package (the .deb is written to the parent directory) +dpkg-buildpackage -us -uc -b +ls ../numbatui_*_amd64.deb +``` + +The packaging lives in `debian/` and drives the same CMake build as above +through `debhelper`. See [`debian/README.source`](./debian/README.source) for +the packaging design and how to bump the package version. + ### Note on Docker on macOS The Docker image documented in [Usage](#usage) is Linux-only and ships a Qt diff --git a/cmake/install.cmake b/cmake/install.cmake new file mode 100644 index 000000000..19eac4dfa --- /dev/null +++ b/cmake/install.cmake @@ -0,0 +1,112 @@ +# ------------------------------------------------------------------------------ +# install.cmake +# +# FHS-compliant installation rules used to build distribution packages +# (e.g. Debian .deb via dpkg-buildpackage / debhelper). +# +# Layout produced (prefix defaults to /usr): +# /NumbatUI the GUI binary +# /numbatui symlink -> NumbatUI +# /numbatui_indexer the indexer binary +# /numbatui/data/... runtime data (color schemes, gui, ...) +# /numbatui/user/... user template tree (projects, settings) +# /applications/numbatui.desktop desktop entry +# /mime/packages/numbatui.xml MIME association for *.srctrlprj +# /icons/hicolor/scalable/... scalable application icon +# /icons/hicolor//... rasterized icons (if ImageMagick found) +# +# This module is only meaningful on Linux; macOS uses the bundle logic and +# Windows uses the WiX/installer logic elsewhere in the tree. +# ------------------------------------------------------------------------------ + +if (NOT (UNIX AND NOT APPLE)) + return() +endif() + +include(GNUInstallDirs) + +# Where NumbatUI's own shared data lives, e.g. /usr/share/numbatui +set(NUMBATUI_PKGDATADIR "${CMAKE_INSTALL_DATADIR}/numbatui") + +# --- Binaries ----------------------------------------------------------------- +# ${APP_PROJECT_NAME} -> output name "NumbatUI" +# ${APP_INDEXER_NAME} -> output name "numbatui_indexer" (set via OUTPUT_NAME) +install(TARGETS ${APP_PROJECT_NAME} ${APP_INDEXER_NAME} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" +) + +# Lower-case convenience symlink (the .desktop entry launches "numbatui"). +# Created relative so it stays valid regardless of the install prefix / DESTDIR. +install(CODE " + set(_bindir \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_BINDIR}\") + file(MAKE_DIRECTORY \"\${_bindir}\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E create_symlink + NumbatUI \"\${_bindir}/numbatui\") +") + +# --- Runtime data ------------------------------------------------------------- +# The application resolves resources at /data/... . On an FHS +# install is /share/numbatui (see includesLinux.h). +install(DIRECTORY "${CMAKE_SOURCE_DIR}/bin/app/data/" + DESTINATION "${NUMBATUI_PKGDATADIR}/data" + PATTERN "install" EXCLUDE # Windows-only uninstaller scripts +) + +# User template tree (sample projects + ApplicationSettings template). At first +# launch the app copies /user/ into ~/.config/numbatui/. +install(DIRECTORY "${CMAKE_SOURCE_DIR}/bin/app/user/" + DESTINATION "${NUMBATUI_PKGDATADIR}/user" +) + +# --- Desktop integration ------------------------------------------------------ +install(FILES "${CMAKE_SOURCE_DIR}/setup/Linux/data/numbatui.desktop" + DESTINATION "${CMAKE_INSTALL_DATADIR}/applications" +) + +# shared-mime-info expects the file named after the package. +install(FILES "${CMAKE_SOURCE_DIR}/setup/Linux/data/numbatui-mime.xml" + DESTINATION "${CMAKE_INSTALL_DATADIR}/mime/packages" + RENAME numbatui.xml +) + +# --- Icons -------------------------------------------------------------------- +# Always ship the scalable SVG master. +install(FILES "${CMAKE_SOURCE_DIR}/logo/numbat_ui.svg" + DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps" + RENAME numbatui.svg +) + +# Additionally rasterize standard hicolor sizes when ImageMagick is available so +# the icon shows up in environments that do not render SVG theme icons. This is +# wired into the build graph (a dependency of the GUI target) rather than done +# at install time, so the generated files exist before `cmake --install`. +find_program(IMAGEMAGICK_CONVERT NAMES magick convert) +if (IMAGEMAGICK_CONVERT) + set(_icon_master "${CMAKE_SOURCE_DIR}/logo/numbatui_1024.png") + set(_icon_sizes 16 32 48 64 128 256 512) + set(_icon_outputs "") + foreach (_sz IN LISTS _icon_sizes) + set(_out "${CMAKE_BINARY_DIR}/icons/${_sz}x${_sz}/numbatui.png") + add_custom_command( + OUTPUT "${_out}" + COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_BINARY_DIR}/icons/${_sz}x${_sz}" + COMMAND "${IMAGEMAGICK_CONVERT}" "${_icon_master}" + -resize "${_sz}x${_sz}" "${_out}" + DEPENDS "${_icon_master}" + COMMENT "Generating ${_sz}x${_sz} application icon" + VERBATIM + ) + list(APPEND _icon_outputs "${_out}") + install(FILES "${_out}" + DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/${_sz}x${_sz}/apps" + ) + endforeach() + add_custom_target(numbatui_icons ALL DEPENDS ${_icon_outputs}) + if (TARGET ${APP_PROJECT_NAME}) + add_dependencies(${APP_PROJECT_NAME} numbatui_icons) + endif() +else() + message(STATUS "ImageMagick not found: only the scalable SVG icon will be installed.") +endif() + +message(STATUS "Install rules enabled (prefix: ${CMAKE_INSTALL_PREFIX}, data: ${NUMBATUI_PKGDATADIR})") diff --git a/cmake/productVersion.h.in b/cmake/productVersion.h.in index 357a31819..06053a69e 100644 --- a/cmake/productVersion.h.in +++ b/cmake/productVersion.h.in @@ -5,7 +5,7 @@ #define GIT_VERSION_NUMBER "@GIT_VERSION_NUMBER@" #define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@" #define GIT_COMMIT_TIME "@GIT_COMMIT_TIME@" -#define VERSION_YEAR @VERSION_YEAR@ +#define VERSION_MAJOR @VERSION_MAJOR@ #define VERSION_MINOR @VERSION_MINOR@ #define VERSION_COMMIT @VERSION_COMMIT@ diff --git a/cmake/version.cmake b/cmake/version.cmake index ca3ad5c89..287df5c9e 100644 --- a/cmake/version.cmake +++ b/cmake/version.cmake @@ -2,8 +2,8 @@ set(GIT_BRANCH "") set(GIT_COMMIT_HASH "") set(GIT_VERSION_NUMBER "") -set(VERSION_YEAR "0") -set(VERSION_MINOR "0") +set(VERSION_MAJOR "0") +set(VERSION_MINOR "1") set(VERSION_COMMIT "0") # set(BUILD_TYPE "") # if(EXISTS "${CMAKE_SOURCE_DIR}/.git") @@ -36,12 +36,12 @@ set(VERSION_COMMIT "0") # OUTPUT_VARIABLE GIT_VERSION_NUMBER # OUTPUT_STRIP_TRAILING_WHITESPACE # ) -# string(REGEX REPLACE "^([0-9]+)\\..*" "\\1" VERSION_YEAR "${GIT_VERSION_NUMBER}") +# string(REGEX REPLACE "^([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GIT_VERSION_NUMBER}") # string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${GIT_VERSION_NUMBER}") # string(REGEX REPLACE "^[0-9]+\\.[0-9]+-([0-9]+).*" "\\1" VERSION_COMMIT "${GIT_VERSION_NUMBER}") # endif(EXISTS "${CMAKE_SOURCE_DIR}/.git") -set(VERSION_STRING "${VERSION_YEAR}.${VERSION_MINOR}.${VERSION_COMMIT}") +set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_COMMIT}") message(STATUS "Version: ${VERSION_STRING}") @@ -49,6 +49,6 @@ message(STATUS "Version: ${VERSION_STRING}") # message(STATUS "Git version number: " ${GIT_VERSION_NUMBER} ) # message(STATUS "Git commit hash: ${GIT_COMMIT_HASH}") # message(STATUS "Git commit time: ${GIT_COMMIT_TIME}") -# message(STATUS "Version year: ${VERSION_YEAR}") +# message(STATUS "Version year: ${VERSION_MAJOR}") # message(STATUS "Version minor: ${VERSION_MINOR}") # message(STATUS "Version commit: ${VERSION_COMMIT}") diff --git a/debian/NumbatUI.1 b/debian/NumbatUI.1 new file mode 100644 index 000000000..8b98dac3b --- /dev/null +++ b/debian/NumbatUI.1 @@ -0,0 +1,43 @@ +.TH NUMBATUI 1 "2026-06-04" "NumbatUI" "User Commands" +.SH NAME +NumbatUI \- source code and graph explorer +.SH SYNOPSIS +.B NumbatUI +.RI [ PROJECT ] +.br +.B NumbatUI +.B index +.RI [ options ] +.I PROJECT +.SH DESCRIPTION +.B NumbatUI +is an interactive source explorer, a Quarkslab fork of Sourcetrail. It lets +you navigate code and graph-based data through linked graph and code views. +.PP +When started without arguments it opens the graphical interface. A project +file (extension +.IR .srctrlprj ) +may be passed to open it directly. +.SH OPTIONS +.TP +.BI index " PROJECT" +Index the given project from the command line without starting the graphical +interface. +.TP +.B \-\-help +Show the full list of commands and options and exit. +.TP +.B \-\-version +Show version information and exit. +.SH FILES +.TP +.I ~/.config/numbatui/ +Per-user configuration, application settings and sample projects, populated on +first launch. +.TP +.I /usr/share/numbatui/ +Read-only application data (color schemes, fonts, GUI resources). +.SH SEE ALSO +.BR numbatui_indexer (1) +.PP +Project home page: . diff --git a/debian/README.source b/debian/README.source new file mode 100644 index 000000000..d6c2906bb --- /dev/null +++ b/debian/README.source @@ -0,0 +1,100 @@ +Packaging notes for NumbatUI +============================ + +This directory contains the Debian packaging for NumbatUI. The package is +built with debhelper (compat 13) on top of the upstream CMake build. + +Source format +------------- + +The package uses the `3.0 (native)` source format (see `debian/source/format`). +NumbatUI is a work-in-progress fork with no upstream release tarballs, and the +packaging lives in the upstream tree, so a native package keeps the build +self-contained: `dpkg-buildpackage` works directly on a git checkout with no +separate `.orig.tar` to assemble. + +When upstream starts publishing release tarballs, switch to `3.0 (quilt)` by +changing `debian/source/format`, using an upstream version without a Debian +revision suffix (e.g. `1.2.0-1`), and providing a matching `.orig.tar.*`. + +Build configuration +------------------- + +`debian/rules` drives CMake via `--buildsystem=cmake` and: + + * configures a Release build with the C/C++ and Python language packages + disabled (`-DBUILD_CXX_LANGUAGE_PACKAGE=OFF`, + `-DBUILD_PYTHON_LANGUAGE_PACKAGE=OFF`), matching the upstream default, and + turns off `-DTREAT_WARNINGS_AS_ERRORS` so the package builds across the + compiler versions found on different releases; + * builds the `NumbatUI` and `NumbatUI_indexer` targets explicitly (so the + test targets are not built and packaged); + * skips the upstream test target, which needs fixtures not relevant to the + package. + +Install layout (FHS) +-------------------- + +Installation is handled by `cmake/install.cmake`, included from the top-level +`CMakeLists.txt`. With the default `/usr` prefix it produces: + + /usr/bin/NumbatUI GUI binary + /usr/bin/numbatui symlink -> NumbatUI (used by the + desktop entry) + /usr/bin/numbatui_indexer indexer binary + /usr/share/numbatui/data/... runtime data (color schemes, gui, + fonts, ...) + /usr/share/numbatui/user/... user template tree copied into + ~/.config/numbatui on first launch + /usr/share/applications/numbatui.desktop desktop entry + /usr/share/mime/packages/numbatui.xml MIME type for *.srctrlprj + /usr/share/icons/hicolor/scalable/... scalable icon (always) + /usr/share/icons/hicolor//... rasterized icons (when ImageMagick + is available at build time) + +At runtime the application locates its data relative to the executable: the +Linux startup code (`src/lib_gui/platform_includes/includesLinux.h`) detects an +FHS install by checking for `/../share/numbatui/data` and sets the +shared data directory to `/share/numbatui`. Keep these two in sync if +the install path of the data ever changes. + +The MIME and icon caches are refreshed automatically on install/removal through +the file triggers owned by `shared-mime-info` and the hicolor icon theme; the +package therefore ships no maintainer-script snippets for them. + +Bumping the version +------------------- + +The package version comes from `debian/changelog`, independently of the +internal CMake version. To cut a new packaging revision: + + dch -v "Describe the change" + +CI builds use whatever version is at the top of `debian/changelog`. + +Continuous integration +---------------------- + +`.github/workflows/deb.yml` builds the package in a `debian:trixie` container on +every push to `main` and `dev` and on pull requests. The resulting `.deb` is +uploaded as a workflow artifact; pushes of a `v*` tag additionally attach it to +the corresponding GitHub release. + +Known lintian notes +-------------------- + + * `embedded-library` (sqlite, tinyxml): NumbatUI statically links vendored + copies of SQLite (via CppSQLite) and TinyXML, inherited from upstream + Sourcetrail. Linking the system `libsqlite3`/`libtinyxml` instead would be + preferable but needs upstream build changes; the tag is overridden in + `debian/numbatui.lintian-overrides` for now. + * `duplicate-font-file`: NumbatUI bundles the Roboto fonts under + `/usr/share/numbatui/data/fonts` and loads them from that fixed path. + Replacing the bundled copies with a dependency on `fonts-roboto-unhinted` + plus symlinks would silence this; overridden for now. + +The build also disables the install RPATH (`-DCMAKE_SKIP_INSTALL_RPATH=ON` in +`debian/rules`): upstream sets an `$ORIGIN/lib` RPATH for the bundled +AppImage/tarball, which is meaningless on a system install and otherwise trips +the `relative-library-search-path` check. Man pages for the installed binaries +are shipped from `debian/*.1` via `debian/numbatui.manpages`. diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..0c8e22a47 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,12 @@ +numbatui (0.0.0+git20260604) unstable; urgency=medium + + * Initial Debian packaging. + * Add FHS install rules (cmake/install.cmake) and discovery of the + /usr/share/numbatui data directory at runtime. + * Build the GUI and indexer with the C/C++ and Python language packages + disabled, matching the upstream default configuration. + * Disable the install RPATH so the binaries carry no relative library + search path on a system install. + * Ship man pages for the installed binaries. + + -- Quarkslab Thu, 04 Jun 2026 09:13:11 +0000 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..d95ea656b --- /dev/null +++ b/debian/control @@ -0,0 +1,35 @@ +Source: numbatui +Section: devel +Priority: optional +Maintainer: Quarkslab +Build-Depends: + debhelper-compat (= 13), + cmake (>= 3.25), + pkg-config, + qt6-base-dev, + qt6-base-dev-tools, + qt6-svg-dev, + qt6-5compat-dev, + libgl-dev, + libboost-filesystem-dev, + libboost-program-options-dev, + libboost-system-dev, + libboost-date-time-dev, + imagemagick, +Standards-Version: 4.6.2 +Homepage: https://github.com/quarkslab/NumbatUI +Rules-Requires-Root: no + +Package: numbatui +Architecture: any +Depends: + ${shlibs:Depends}, + ${misc:Depends}, +Description: source code and graph explorer (Quarkslab fork of Sourcetrail) + NumbatUI is a fork of Sourcetrail, an interactive source explorer that lets + you navigate code through linked graph and code views. It is designed to + explore graph-based data generated by Numbat. + . + This package ships the GUI application and its indexer. The C/C++ and Python + language indexing back-ends are disabled in this build and will be enabled in + a future release. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000000000..3c56999e4 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,29 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: NumbatUI +Upstream-Contact: Quarkslab +Source: https://github.com/quarkslab/NumbatUI + +Files: * +Copyright: 2024-2026 Quarkslab + 2014-2021 Coati Software KG (Sourcetrail) +License: GPL-3.0+ + +Files: debian/* +Copyright: 2026 Quarkslab +License: GPL-3.0+ + +License: GPL-3.0+ + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + . + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License along with + this program. If not, see . + . + On Debian systems, the complete text of the GNU General Public License + version 3 can be found in "/usr/share/common-licenses/GPL-3". diff --git a/debian/numbatui.1 b/debian/numbatui.1 new file mode 100644 index 000000000..5ef47d7a5 --- /dev/null +++ b/debian/numbatui.1 @@ -0,0 +1 @@ +.so man1/NumbatUI.1 diff --git a/debian/numbatui.lintian-overrides b/debian/numbatui.lintian-overrides new file mode 100644 index 000000000..7d509521f --- /dev/null +++ b/debian/numbatui.lintian-overrides @@ -0,0 +1,12 @@ +# NumbatUI vendors SQLite (via CppSQLite) and TinyXML and compiles them +# statically into the binaries, as inherited from upstream Sourcetrail. +# Unbundling these to link the system libsqlite3/libtinyxml is desirable but +# requires upstream build changes; it is tracked as future work. The embedding +# is intentional and known, so suppress the tag for now. +numbatui: embedded-library + +# The Roboto fonts are shipped under /usr/share/numbatui/data/fonts because the +# application loads its fonts from that fixed resource path. This duplicates the +# fonts-roboto-* packages; replacing the bundled copies with symlinks plus a +# dependency is left for a future change. +numbatui: duplicate-font-file diff --git a/debian/numbatui.manpages b/debian/numbatui.manpages new file mode 100644 index 000000000..2a7561b87 --- /dev/null +++ b/debian/numbatui.manpages @@ -0,0 +1,3 @@ +debian/NumbatUI.1 +debian/numbatui.1 +debian/numbatui_indexer.1 diff --git a/debian/numbatui_indexer.1 b/debian/numbatui_indexer.1 new file mode 100644 index 000000000..ea88a3171 --- /dev/null +++ b/debian/numbatui_indexer.1 @@ -0,0 +1,17 @@ +.TH NUMBATUI_INDEXER 1 "2026-06-04" "NumbatUI" "User Commands" +.SH NAME +numbatui_indexer \- indexing helper for NumbatUI +.SH SYNOPSIS +.B numbatui_indexer +.I process-id instance-uuid app-path user-data-path +.RI [ log-file ] +.SH DESCRIPTION +.B numbatui_indexer +is the worker process used by +.BR NumbatUI (1) +to index source projects. It is normally launched automatically by the +graphical application and is not intended to be invoked directly by users. +.SH SEE ALSO +.BR NumbatUI (1) +.PP +Project home page: . diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000..57d307130 --- /dev/null +++ b/debian/rules @@ -0,0 +1,27 @@ +#!/usr/bin/make -f +# Build NumbatUI as a Debian package using the CMake buildsystem driven by +# debhelper. See debhelper(7) and dh(1). + +# Enable verbose CMake/build output, useful for diagnosing CI build failures. +export DH_VERBOSE = 1 + +%: + dh $@ --buildsystem=cmake + +override_dh_auto_configure: + dh_auto_configure -- \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_CXX_LANGUAGE_PACKAGE=OFF \ + -DBUILD_PYTHON_LANGUAGE_PACKAGE=OFF \ + -DTREAT_WARNINGS_AS_ERRORS=OFF \ + -DCMAKE_SKIP_INSTALL_RPATH=ON + +# Build the GUI and the indexer explicitly. This avoids building the (test) +# targets, which are not packaged, and does not rely on the GUI target's +# dependency on the indexer to pull the latter in. +override_dh_auto_build: + dh_auto_build -- NumbatUI NumbatUI_indexer + +# The upstream test target requires test fixtures that are not part of the +# packaging build; skip the test phase. +override_dh_auto_test: diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000000000..89ae9db8f --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 000000000..290b3f4dc --- /dev/null +++ b/debian/source/options @@ -0,0 +1,5 @@ +# Keep the .git directory and build artifacts out of the generated source +# tarball when building the native package. +tar-ignore = ".git" +tar-ignore = "build" +tar-ignore = "obj-*" diff --git a/setup/Linux/data/numbatui.desktop b/setup/Linux/data/numbatui.desktop index 74a45e652..30051f709 100644 --- a/setup/Linux/data/numbatui.desktop +++ b/setup/Linux/data/numbatui.desktop @@ -3,11 +3,12 @@ Name=NumbatUI GenericName=NumbatUI X-GNOME-FullName=NumbatUI Comment=Source Code & Graph Explorer -Exec=/usr/bin/numbatui +Exec=numbatui %f Icon=numbatui Terminal=false Type=Application MimeType=application/x-numbatui; Categories=Development; +Keywords=source;code;graph;explorer;sourcetrail;indexer; StartupNotify=true StartupWMClass=NumbatUI diff --git a/src/app/main.cpp b/src/app/main.cpp index 3faaba6cb..bf52b568b 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -98,7 +98,7 @@ int main(int argc, char* argv[]) QApplication::setApplicationName(QStringLiteral("NumbatUI")); - Version version(VERSION_YEAR, VERSION_MINOR, VERSION_COMMIT, GIT_COMMIT_HASH); + Version version(VERSION_MAJOR, VERSION_MINOR, VERSION_COMMIT, GIT_COMMIT_HASH); QApplication::setApplicationVersion(version.toDisplayString().c_str()); MessageStatus( diff --git a/src/lib/utility/utility.h b/src/lib/utility/utility.h index 794b0010e..7d8106e1f 100644 --- a/src/lib/utility/utility.h +++ b/src/lib/utility/utility.h @@ -240,19 +240,16 @@ std::vector utility::toVector(const std::deque& d) template std::vector utility::toVector(const std::set& d) { - std::vector v; - v.reserve(d.size()); - v.insert(v.begin(), d.begin(), d.end()); - return v; + // Construct directly from the range instead of insert(begin(), ...): the + // latter makes libstdc++ call std::advance() with an unsigned count, which + // triggers a spurious -Waggressive-loop-optimizations warning. + return std::vector(d.begin(), d.end()); } template std::vector utility::toVector(const std::list& d) { - std::vector v; - v.reserve(d.size()); - v.insert(v.begin(), d.begin(), d.end()); - return v; + return std::vector(d.begin(), d.end()); } template diff --git a/src/lib_gui/platform_includes/includesLinux.h b/src/lib_gui/platform_includes/includesLinux.h index d48df58b8..978ad8caa 100644 --- a/src/lib_gui/platform_includes/includesLinux.h +++ b/src/lib_gui/platform_includes/includesLinux.h @@ -50,11 +50,18 @@ void setupApp(int argc, char* argv[]) AppPath::setSharedDataDirectoryPath(appPath); AppPath::setCxxIndexerDirectoryPath(appPath); - // Check if bundled as Linux AppImage + // Check if bundled as Linux AppImage / tarball (data sits in ../share/data) if (appPath.getConcatenated(L"/../share/data").exists()) { AppPath::setSharedDataDirectoryPath(appPath.getConcatenated(L"/../share").getAbsolute()); } + // Check if installed following the FHS, e.g. from a distribution package: + // binary in /bin, shared data in /share/numbatui. + else if (appPath.getConcatenated(L"/../share/numbatui/data").exists()) + { + AppPath::setSharedDataDirectoryPath( + appPath.getConcatenated(L"/../share/numbatui").getAbsolute()); + } std::string userdir(std::getenv("HOME")); userdir.append("/.config/numbatui/"); diff --git a/src/lib_gui/qt/element/search/QtScreenSearchBox.cpp b/src/lib_gui/qt/element/search/QtScreenSearchBox.cpp index 651df76ce..d2c4685e4 100644 --- a/src/lib_gui/qt/element/search/QtScreenSearchBox.cpp +++ b/src/lib_gui/qt/element/search/QtScreenSearchBox.cpp @@ -156,7 +156,11 @@ void QtScreenSearchBox::addResponder(const std::string& name) m_checkBoxes.emplace(name, box); m_checkboxLayout->addWidget(box); +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) + connect(box, &QCheckBox::checkStateChanged, this, &QtScreenSearchBox::findMatches); +#else connect(box, &QCheckBox::stateChanged, this, &QtScreenSearchBox::findMatches); +#endif } void QtScreenSearchBox::setFocus() diff --git a/src/lib_gui/qt/view/QtErrorView.cpp b/src/lib_gui/qt/view/QtErrorView.cpp index 09996c10a..4baec468b 100644 --- a/src/lib_gui/qt/view/QtErrorView.cpp +++ b/src/lib_gui/qt/view/QtErrorView.cpp @@ -336,11 +336,17 @@ QCheckBox* QtErrorView::createFilterCheckbox(const QString& name, bool checked, QCheckBox* checkbox = new QCheckBox(name); checkbox->setChecked(checked); +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) + connect(checkbox, &QCheckBox::checkStateChanged, this, [this](Qt::CheckState state) { + errorFilterChanged(static_cast(state)); + }); +#else connect( checkbox, &QCheckBox::stateChanged, this, static_cast(&QtErrorView::errorFilterChanged)); +#endif layout->addWidget(checkbox); layout->addSpacing(25); diff --git a/src/lib_gui/qt/view/QtStatusView.cpp b/src/lib_gui/qt/view/QtStatusView.cpp index e20a82049..44c275671 100644 --- a/src/lib_gui/qt/view/QtStatusView.cpp +++ b/src/lib_gui/qt/view/QtStatusView.cpp @@ -137,14 +137,19 @@ QCheckBox* QtStatusView::createFilterCheckbox(const QString& name, QBoxLayout* l QCheckBox* checkbox = new QCheckBox(name); checkbox->setChecked(checked); - connect(checkbox, &QCheckBox::stateChanged, [=](int) { + auto onCheckStateChanged = [=]() { m_table->selectionModel()->clearSelection(); const StatusFilter statusMask = (m_showInfo->isChecked() ? StatusType::STATUS_INFO : 0) + (m_showErrors->isChecked() ? StatusType::STATUS_ERROR : 0); MessageStatusFilterChanged(statusMask).dispatch(); - }); + }; +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) + connect(checkbox, &QCheckBox::checkStateChanged, onCheckStateChanged); +#else + connect(checkbox, &QCheckBox::stateChanged, onCheckStateChanged); +#endif layout->addWidget(checkbox); diff --git a/src/lib_gui/utility/utilityApp.cpp b/src/lib_gui/utility/utilityApp.cpp index e4d894ad7..c848056b6 100644 --- a/src/lib_gui/utility/utilityApp.cpp +++ b/src/lib_gui/utility/utilityApp.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -67,16 +68,24 @@ namespace template bool safely_wait_for(boost::process::child& process, const std::chrono::duration& rel_time) { - // This wrapper around boost::process::wait_for handles the following edge case: - // Calling wait_for on an already exitted process will wait for the entire timeout. - if (process.running()) + // Poll child::running() until the process exits or the timeout elapses, + // instead of boost::process::child::wait_for, which is deprecated and + // documented as unreliable. running() reaps the process once it has exited, + // so the exit code is available afterwards. + // + // This also handles the edge case the previous implementation guarded + // against: an already-exited process returns immediately rather than + // blocking for the whole timeout. + const auto deadline = std::chrono::steady_clock::now() + rel_time; + while (process.running()) { - return process.wait_for(rel_time); - } - else - { - return true; // The process exitted + if (std::chrono::steady_clock::now() >= deadline) + { + return false; // still running when the timeout elapsed + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } + return true; // the process exited } } // namespace