Browse Source

Flatpak, use host system headers and run external programs outside of sandbox

merge-requests/413/head
doe300 3 years ago
parent
commit
69a30f271d
  1. 6
      CMakeLists.txt
  2. 4
      jucipp.yaml
  3. 2
      lib/tiny-process-library
  4. 13
      src/compile_commands.cpp
  5. 6
      src/config.cpp
  6. 8
      src/ctags.cpp
  7. 12
      src/filesystem.cpp
  8. 12
      src/source.cpp
  9. 7
      src/source_language_protocol.cpp
  10. 22
      src/terminal.cpp

6
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

4
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

2
lib/tiny-process-library

@ -1 +1 @@
Subproject commit 839ff806dc447ff49af80f9a9eaa7949f770f8e5
Subproject commit 27bf021d97d428b3c0cef4009cb9c03ad46c4376

13
src/compile_commands.cpp

@ -167,10 +167,17 @@ std::vector<std::string> 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<std::string> 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");

6
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)) {

8
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;

12
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();

12
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<TinyProcessLib::Process>(
"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");
}

7
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<TinyProcessLib::Process>(
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> LanguageProtocol::Client::get(const boost::filesystem::path &file_path, const std::string &language_id, const std::string &language_server) {

22
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<TinyProcessLib::Process> process;
TinyProcessLib::Config processConfig{};
#ifdef JUCI_FLATPAK_SANDBOX
processConfig.flatpak_spawn_host = true;
#endif
if(use_pipes)
process = std::make_unique<TinyProcessLib::Process>(
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<TinyProcessLib::Process>(command, path.string());
process = std::make_unique<TinyProcessLib::Process>(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<TinyProcessLib::Process> 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<TinyProcessLib::Process>(
#if defined(__APPLE__)
"STDBUF1=L " + command,
@ -321,7 +335,7 @@ std::shared_ptr<TinyProcessLib::Process> Terminal::async_process(const std::stri
message_printed.get_future().get();
}
},
true);
true, processConfig);
auto pid = process->get_id();
if(pid <= 0) {

Loading…
Cancel
Save