From b9fcb0195b0db8437f3aeb39f92dd6c4aabb9e85 Mon Sep 17 00:00:00 2001 From: doe300 Date: Sat, 9 Jul 2022 10:42:55 +0200 Subject: [PATCH 1/2] Add flatpak manifest Implements #341, closes #403 --- CMakeLists.txt | 1 + jucipp.yaml | 234 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 jucipp.yaml diff --git a/CMakeLists.txt b/CMakeLists.txt index 42f1660..c297cdd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,6 +76,7 @@ option(BUILD_TESTING "Build tests") option(BUILD_FUZZING "Build tests") option(LIBCLANG_PATH "Use custom path for libclang") option(LIBLLDB_PATH "Use custom path for liblldb") +option(FLATPAK_SANDBOX "Runs from within a flatpak sandbox") # This is forwarded to the tiny-process-library submodule find_package(Boost 1.54 COMPONENTS REQUIRED filesystem serialization) find_package(ASPELL REQUIRED) diff --git a/jucipp.yaml b/jucipp.yaml new file mode 100644 index 0000000..ced0cff --- /dev/null +++ b/jucipp.yaml @@ -0,0 +1,234 @@ +id: com.gitlab.cppit.jucipp +command: juci + +# Install via: flatpak install flathub org.gnome.Platform//42 org.gnome.Sdk//42 +runtime: org.gnome.Platform +runtime-version: '42' +sdk: org.gnome.Sdk +sdk-extensions: + # Install via: flatpak install flathub org.freedesktop.Sdk.Extension.llvm14 + - org.freedesktop.Sdk.Extension.llvm14 + +rename-desktop-file: juci.desktop +rename-icon: juci +finish-args: + - --socket=x11 + - --share=ipc # somewhat required by X11 + - --socket=wayland + - --share=network # Unix sockets are e.g. used by X11 + - --filesystem=host:rw # access all files on the host + - --filesystem=home:rw # access all files on the host + - --talk-name=org.freedesktop.Flatpak # allows to run processes outside of flatpak sandbox + - --persist=.juci # persist configuration + +modules: + - name: boost + buildsystem: simple + sources: + - type: archive + url: https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2 + sha256: 475d589d51a7f8b3ba2ba4eda022b170e562ca3b760ee922c146b6c65856ef39 + build-commands: + - ./bootstrap.sh --prefix="${FLATPAK_DEST}" --with-libraries=filesystem,serialization + - ./b2 -j $FLATPAK_BUILDER_N_JOBS install + cleanup: + - /include + - '/lib/libboost_*.a' + - /lib/cmake + - /lib/debug + - /lib/pkgconfig + + - name: mm-common # build-dependency of gtkmm + sources: + - type: archive + url: https://download.gnome.org/sources/mm-common/1.0/mm-common-1.0.4.tar.xz + sha256: e954c09b4309a7ef93e13b69260acdc5738c907477eb381b78bb1e414ee6dbd8 + cleanup: + - '*' + + - name: sigc++-2 # dependency of gtkmm + buildsystem: autotools + config-opts: + - --disable-documentation + sources: + - type: archive + url: https://download.gnome.org/sources/libsigc%2B%2B/2.10/libsigc%2B%2B-2.10.8.tar.xz + sha256: 235a40bec7346c7b82b6a8caae0456353dc06e71f14bc414bcc858af1838719a + cleanup: + - /include + - /lib/debug + - /lib/sigc++-2.0 + - /lib/pkgconfig + - /lib/libsigc-2.0.la + + - name: glibmm # dependency of gtkmm + buildsystem: meson + sources: + - type: archive + url: https://download.gnome.org/sources/glibmm/2.66/glibmm-2.66.2.tar.xz + sha256: b2a4cd7b9ae987794cbb5a1becc10cecb65182b9bb841868625d6bbb123edb1d + cleanup: + - /include + - /lib/debug + - /lib/giomm-2.4 + - /lib/glibmm-2.4 + - /lib/pkgconfig + + - name: cairomm # dependency of gtkmm + buildsystem: autotools + config-opts: + - --disable-documentation + sources: + - type: archive + url: https://www.cairographics.org/releases/cairomm-1.14.3.tar.xz + sha256: 0d37e067c5c4ca7808b7ceddabfe1932c5bd2a750ad64fb321e1213536297e78 + cleanup: + - /include + - /lib/cairomm-1.0 + - /lib/debug + - /lib/pkgconfig + - /lib/libcairomm-1.0.la + + - name: pangomm # dependency of gtkmm + buildsystem: meson + sources: + - type: archive + url: https://download.gnome.org/sources/pangomm/2.46/pangomm-2.46.2.tar.xz + sha256: 57442ab4dc043877bfe3839915731ab2d693fc6634a71614422fb530c9eaa6f4 + cleanup: + - /include + - /lib/debug + - /lib/pangomm-1.4 + - /lib/pkgconfig + + - name: atkmm # dependency of gtkmm + buildsystem: meson + sources: + - type: archive + url: https://download.gnome.org/sources/atkmm/2.28/atkmm-2.28.2.tar.xz + sha256: a0bb49765ceccc293ab2c6735ba100431807d384ffa14c2ebd30e07993fd2fa4 + cleanup: + - /include + - /lib/atkmm-1.6 + - /lib/debug + - /lib/pkgconfig + + - name: gtkmm + buildsystem: meson + sources: + - type: archive + url: https://download.gnome.org/sources/gtkmm/3.24/gtkmm-3.24.5.tar.xz + sha256: 856333de86689f6a81c123f2db15d85db9addc438bc3574c36f15736aeae22e6 + cleanup: + - /include + - /lib/debug + - /lib/gdkmm-3.0 + - /lib/gtkmm-3.0 + - /lib/pkgconfig + + - name: gtksourceview # dependency of gtksourceviewmm + buildsystem: autotools + config-opts: + - --disable-documentation + sources: + - type: archive + url: https://download.gnome.org/sources/gtksourceview/3.24/gtksourceview-3.24.11.tar.xz + sha256: 691b074a37b2a307f7f48edc5b8c7afa7301709be56378ccf9cc9735909077fd + cleanup: + - /include + - /lib/debug + - /lib/pkgconfig + - /lib/libgtksourceview-3.0.la + - /share/gtk-doc + - /share/vala + + - name: gtksourceviewmm + buildsystem: autotools + config-opts: + - --disable-documentation + sources: + - type: archive + url: https://download.gnome.org/sources/gtksourceviewmm/3.21/gtksourceviewmm-3.21.3.tar.xz + sha256: dbb00b1c28e0407cc27d8b07a2ed0b4ea22f92e4b3e3006431cbd6726b6256b5 + cleanup: + - /include + - /lib/debug + - /lib/gtksourceviewmm-3.0 + - /lib/pkgconfig + - /lib/libgtksourceviewmm-3.0.la + + - name: ncurses # build-depencendy of aspell (required to build aspell executable) + buildsystem: autotools + sources: + - type: archive + url: https://ftp.gnu.org/gnu/ncurses/ncurses-6.3.tar.gz + sha256: 97fc51ac2b085d4cde31ef4d2c3122c21abc217e9090a43a30fc5ec21684e059 + cleanup: + - '*' + + - name: aspell + buildsystem: autotools + sources: + - type: archive + url: https://ftp.gnu.org/gnu/aspell/aspell-0.60.8.tar.gz + sha256: f9b77e515334a751b2e60daab5db23499e26c9209f5e7b7443b05235ad0226f2 + cleanup: + - /bin + - /include + - /lib/debug + - /lib/pkgconfig + - /lib/libaspell.la + - '/lib/libpspell.*' + - /share/info + - /share/man + + - name: aspell-en + buildsystem: simple + sources: + - type: archive + url: https://ftp.gnu.org/gnu/aspell/dict/en/aspell6-en-2020.12.07-0.tar.bz2 + sha256: 4c8f734a28a088b88bb6481fcf972d0b2c3dc8da944f7673283ce487eac49fb3 + build-commands: + - ./configure + - make -j $FLATPAK_BUILDER_N_JOBS + - make install + + - name: libgit2 + buildsystem: cmake + config-opts: + - -DBUILD_TESTS=OFF + sources: + - type: archive + url: https://github.com/libgit2/libgit2/archive/refs/tags/v1.4.3.tar.gz + sha256: f48b961e463a9e4e7e7e58b21a0fb5a9b2a1d24d9ba4d15870a0c9b8ad965163 + cleanup: + - /include + - /lib/debug + - /lib/pkgconfig + + - name: jucipp + buildsystem: simple + build-options: + append-path: /usr/lib/sdk/llvm14/bin + prepend-ld-library-path: /usr/lib/sdk/llvm14/lib + sources: + - type: git + branch: gcc11_fix + url: https://gitlab.com/cppit/jucipp.git + build-commands: + - cp -r /usr/lib/sdk/llvm14/lib/* /app/lib/ + - cp -r /usr/lib/sdk/llvm14/include/* /app/include/ + - cmake -DCMAKE_INSTALL_PREFIX=${FLATPAK_DEST} -DFLATPAK_SANDBOX=ON . + - cmake --build . -- -j $FLATPAK_BUILDER_N_JOBS + - make install + cleanup: + - /include + - /lib/clang + - /lib/cmake + - /lib/debug/lib + - /lib/libear + - /lib/libscanbuild + - /lib/python3.9 + - '/lib/libLTO.*' + - '/lib/libRemarks.*' + - /lib/LLVMgold.so From 69a30f271d51138005876e05572d8b72df82e012 Mon Sep 17 00:00:00 2001 From: doe300 Date: Mon, 12 Sep 2022 17:09:43 +0200 Subject: [PATCH 2/2] Flatpak, use host system headers and run external programs outside of sandbox --- CMakeLists.txt | 6 +++++- jucipp.yaml | 4 ++-- lib/tiny-process-library | 2 +- src/compile_commands.cpp | 13 ++++++++++--- src/config.cpp | 6 +++++- src/ctags.cpp | 8 +++++++- src/filesystem.cpp | 12 ++++++++++-- src/source.cpp | 12 ++++++++++-- src/source_language_protocol.cpp | 7 ++++++- src/terminal.cpp | 22 ++++++++++++++++++---- 10 files changed, 74 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c297cdd..32e7c4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,7 @@ option(BUILD_TESTING "Build tests") option(BUILD_FUZZING "Build tests") option(LIBCLANG_PATH "Use custom path for libclang") option(LIBLLDB_PATH "Use custom path for liblldb") -option(FLATPAK_SANDBOX "Runs from within a flatpak sandbox") # This is forwarded to the tiny-process-library submodule +option(FLATPAK_SANDBOX "Runs from within a flatpak sandbox") find_package(Boost 1.54 COMPONENTS REQUIRED filesystem serialization) find_package(ASPELL REQUIRED) @@ -129,6 +129,10 @@ else() message("liblldb not found. Building juCi++ without debugging support") endif() +if(FLATPAK_SANDBOX) + add_definitions(-DJUCI_FLATPAK_SANDBOX) +endif() + if(CMAKE_SYSTEM_NAME MATCHES .*BSD|DragonFly) add_definitions(-DJUCI_USE_UCTAGS) # See https://svnweb.freebsd.org/ports?view=revision&revision=452957 add_definitions(-DJUCI_USE_GREP_EXCLUDE) # --exclude-dir is not an argument in bsd grep diff --git a/jucipp.yaml b/jucipp.yaml index ced0cff..ee7846b 100644 --- a/jucipp.yaml +++ b/jucipp.yaml @@ -213,7 +213,7 @@ modules: prepend-ld-library-path: /usr/lib/sdk/llvm14/lib sources: - type: git - branch: gcc11_fix + branch: master url: https://gitlab.com/cppit/jucipp.git build-commands: - cp -r /usr/lib/sdk/llvm14/lib/* /app/lib/ @@ -225,7 +225,7 @@ modules: - /include - /lib/clang - /lib/cmake - - /lib/debug/lib + - /lib/debug - /lib/libear - /lib/libscanbuild - /lib/python3.9 diff --git a/lib/tiny-process-library b/lib/tiny-process-library index 839ff80..27bf021 160000 --- a/lib/tiny-process-library +++ b/lib/tiny-process-library @@ -1 +1 @@ -Subproject commit 839ff806dc447ff49af80f9a9eaa7949f770f8e5 +Subproject commit 27bf021d97d428b3c0cef4009cb9c03ad46c4376 diff --git a/src/compile_commands.cpp b/src/compile_commands.cpp index b13494d..f48dec7 100644 --- a/src/compile_commands.cpp +++ b/src/compile_commands.cpp @@ -167,10 +167,17 @@ std::vector CompileCommands::get_arguments(const boost::filesystem: else arguments.emplace_back(default_std_argument); +#ifdef JUCI_FLATPAK_SANDBOX + // The host file system is mounted here, need to add this as prefix to access host system headers + const std::string sysroot = "/var/run/host/"; +#else + const std::string sysroot = ""; +#endif + static FindSystemIncludePaths system_include_paths; if(system_include_paths) { for(auto &path : system_include_paths.include_paths) - arguments.emplace_back("-I" + path); + arguments.emplace_back("-I" + sysroot + path); for(auto &path : system_include_paths.framework_paths) arguments.emplace_back("-F" + path); #ifdef _WIN32 @@ -191,8 +198,8 @@ std::vector CompileCommands::get_arguments(const boost::filesystem: std::smatch sm; if(std::regex_match(clang_version_string, sm, clang_version_regex)) { auto clang_version = sm[1].str(); - arguments.emplace_back("-I/usr/lib/clang/" + clang_version + "/include"); - arguments.emplace_back("-I/usr/lib64/clang/" + clang_version + "/include"); // For Fedora + arguments.emplace_back("-I" + sysroot + "/usr/lib/clang/" + clang_version + "/include"); + arguments.emplace_back("-I" + sysroot + "/usr/lib64/clang/" + clang_version + "/include"); // For Fedora #if defined(__APPLE__) // Missing include and framework folders for MacOS: arguments.emplace_back("-I/usr/local/opt/llvm/include/c++/v1"); diff --git a/src/config.cpp b/src/config.cpp index 8c4a7af..43cdc08 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -206,12 +206,16 @@ std::string Config::default_config() { std::string cmake_version; unsigned thread_count = 0; std::stringstream ss; + TinyProcessLib::Config processConfig{}; +#ifdef JUCI_FLATPAK_SANDBOX + processConfig.flatpak_spawn_host = true; +#endif TinyProcessLib::Process process( "cmake --version", "", [&ss](const char *buffer, size_t n) { ss.write(buffer, n); }, - [](const char *buffer, size_t n) {}); + [](const char *buffer, size_t n) {}, false, processConfig); if(process.get_exit_status() == 0) { std::string line; if(std::getline(ss, line)) { diff --git a/src/ctags.cpp b/src/ctags.cpp index 37e2cde..1541dbc 100644 --- a/src/ctags.cpp +++ b/src/ctags.cpp @@ -36,6 +36,11 @@ Ctags::Ctags(const boost::filesystem::path &path, bool enable_scope, bool enable command = Config::get().project.ctags_command + options + fields + " --c-kinds=+p --c++-kinds=+p " + filesystem::escape_argument(path.string()); } + TinyProcessLib::Config processConfig{}; +#ifdef JUCI_FLATPAK_SANDBOX + processConfig.flatpak_spawn_host = true; +#endif + TinyProcessLib::Process process( command, project_path.string(), [this](const char *output, size_t length) { @@ -43,7 +48,8 @@ Ctags::Ctags(const boost::filesystem::path &path, bool enable_scope, bool enable }, [](const char *bytes, size_t n) { Terminal::get().async_print(std::string(bytes, n), true); - }); + }, + false, processConfig); int exit_status; size_t count = 0; diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 59a1b7b..d455fe8 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -132,12 +132,16 @@ const boost::filesystem::path &filesystem::get_home_path() noexcept { const boost::filesystem::path &filesystem::get_rust_sysroot_path() noexcept { auto get_path = [] { std::string path; + TinyProcessLib::Config processConfig{}; +#ifdef JUCI_FLATPAK_SANDBOX + processConfig.flatpak_spawn_host = true; +#endif TinyProcessLib::Process process( "rustc --print sysroot", "", [&path](const char *buffer, size_t length) { path += std::string(buffer, length); }, - [](const char *buffer, size_t n) {}); + [](const char *buffer, size_t n) {}, false, processConfig); if(process.get_exit_status() == 0) { while(!path.empty() && (path.back() == '\n' || path.back() == '\r')) path.pop_back(); @@ -154,13 +158,17 @@ const boost::filesystem::path &filesystem::get_rust_sysroot_path() noexcept { boost::filesystem::path filesystem::get_rust_nightly_sysroot_path() noexcept { auto get_path = [] { std::string path; + TinyProcessLib::Config processConfig{}; +#ifdef JUCI_FLATPAK_SANDBOX + processConfig.flatpak_spawn_host = true; +#endif TinyProcessLib::Process process( // Slightly complicated since "RUSTUP_TOOLCHAIN=nightly rustc --print sysroot" actually installs nightly toolchain if missing... "rustup toolchain list|grep nightly > /dev/null && RUSTUP_TOOLCHAIN=nightly rustc --print sysroot", "", [&path](const char *buffer, size_t length) { path += std::string(buffer, length); }, - [](const char *buffer, size_t n) {}); + [](const char *buffer, size_t n) {}, false, processConfig); if(process.get_exit_status() == 0) { while(!path.empty() && (path.back() == '\n' || path.back() == '\r')) path.pop_back(); diff --git a/src/source.cpp b/src/source.cpp index 2b57562..b2ae290 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -797,12 +797,16 @@ void Source::View::setup_format_style(bool is_generic_view) { static auto get_prettier_library = [] { std::string library; + TinyProcessLib::Config processConfig{}; +#ifdef JUCI_FLATPAK_SANDBOX + processConfig.flatpak_spawn_host = true; +#endif TinyProcessLib::Process process( "npm root -g", "", [&library](const char *buffer, size_t length) { library += std::string(buffer, length); }, - [](const char *, size_t) {}); + [](const char *, size_t) {}, false, processConfig); if(process.get_exit_status() == 0) { while(!library.empty() && (library.back() == '\n' || library.back() == '\r')) library.pop_back(); @@ -859,6 +863,10 @@ void Source::View::setup_format_style(bool is_generic_view) { stdout_buffer = std::stringstream(); curly_count = 0; key_or_value = false; + TinyProcessLib::Config processConfig{1048576}; +#ifdef JUCI_FLATPAK_SANDBOX + processConfig.flatpak_spawn_host = true; +#endif prettier_background_process = std::make_unique( "node -e \"const repl = require('repl');repl.start({prompt: '', ignoreUndefined: true, preview: false});\"", "", @@ -930,7 +938,7 @@ void Source::View::setup_format_style(bool is_generic_view) { LockGuard lock(mutex); error = Error{std::move(message), line, line_index}; }, - true, TinyProcessLib::Config{1048576}); + true, processConfig); prettier_background_process->write("const prettier = require(\"" + escape(prettier_library, {'"'}) + "\");\n"); } diff --git a/src/source_language_protocol.cpp b/src/source_language_protocol.cpp index a8121e0..ad69eaf 100644 --- a/src/source_language_protocol.cpp +++ b/src/source_language_protocol.cpp @@ -112,6 +112,11 @@ LanguageProtocol::WorkspaceEdit::WorkspaceEdit(const JSON &workspace_edit, boost } LanguageProtocol::Client::Client(boost::filesystem::path root_path_, std::string language_id_, const std::string &language_server) : root_path(std::move(root_path_)), language_id(std::move(language_id_)) { + TinyProcessLib::Config processConfig{1048576}; +#ifdef JUCI_FLATPAK_SANDBOX + processConfig.flatpak_spawn_host = true; +#endif + process = std::make_unique( language_server, root_path.string(), [this](const char *bytes, size_t n) { @@ -121,7 +126,7 @@ LanguageProtocol::Client::Client(boost::filesystem::path root_path_, std::string [](const char *bytes, size_t n) { std::cerr.write(bytes, n); }, - true, TinyProcessLib::Config{1048576}); + true, processConfig); } std::shared_ptr LanguageProtocol::Client::get(const boost::filesystem::path &file_path, const std::string &language_id, const std::string &language_server) { diff --git a/src/terminal.cpp b/src/terminal.cpp index 42a1511..3e3390d 100644 --- a/src/terminal.cpp +++ b/src/terminal.cpp @@ -204,6 +204,10 @@ Terminal::Terminal() : Source::CommonView() { int Terminal::process(const std::string &command, const boost::filesystem::path &path, bool use_pipes) { std::unique_ptr process; + TinyProcessLib::Config processConfig{}; +#ifdef JUCI_FLATPAK_SANDBOX + processConfig.flatpak_spawn_host = true; +#endif if(use_pipes) process = std::make_unique( command, path.string(), @@ -212,9 +216,10 @@ int Terminal::process(const std::string &command, const boost::filesystem::path }, [this](const char *bytes, size_t n) { async_print(std::string(bytes, n), true); - }); + }, + false, processConfig); else - process = std::make_unique(command, path.string()); + process = std::make_unique(command, path.string(), nullptr, nullptr, false, processConfig); if(process->get_id() <= 0) { async_print("\e[31mError\e[m: failed to run command: " + command + "\n", true); @@ -225,6 +230,10 @@ int Terminal::process(const std::string &command, const boost::filesystem::path } int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path, std::ostream *stderr_stream) { + TinyProcessLib::Config processConfig{}; +#ifdef JUCI_FLATPAK_SANDBOX + processConfig.flatpak_spawn_host = true; +#endif TinyProcessLib::Process process( command, path.string(), [&stdout_stream](const char *bytes, size_t n) { @@ -243,7 +252,7 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c else async_print(std::string(bytes, n), true); }, - true); + true, processConfig); if(process.get_id() <= 0) { async_print("\e[31mError\e[m: failed to run command: " + command + "\n", true); @@ -288,6 +297,11 @@ std::shared_ptr Terminal::async_process(const std::stri cd_path_and_command = command; #endif + TinyProcessLib::Config processConfig{}; +#ifdef JUCI_FLATPAK_SANDBOX + processConfig.flatpak_spawn_host = true; +#endif + auto process = std::make_shared( #if defined(__APPLE__) "STDBUF1=L " + command, @@ -321,7 +335,7 @@ std::shared_ptr Terminal::async_process(const std::stri message_printed.get_future().get(); } }, - true); + true, processConfig); auto pid = process->get_id(); if(pid <= 0) {