fix
This commit is contained in:
parent
05aa464989
commit
bf40630719
18 changed files with 438 additions and 90 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -45,4 +45,5 @@ test.js
|
|||
.clangd
|
||||
internal_docs/
|
||||
*.flatpak
|
||||
/flatpak-repo/
|
||||
/flatpak-repo/
|
||||
/.idea/
|
||||
|
|
|
|||
8
.idea/.gitignore
generated
vendored
8
.idea/.gitignore
generated
vendored
|
|
@ -1,8 +0,0 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
2
.idea/OrcaSlicer.iml
generated
2
.idea/OrcaSlicer.iml
generated
|
|
@ -1,2 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||
7
.idea/codeStyles/Project.xml
generated
7
.idea/codeStyles/Project.xml
generated
|
|
@ -1,7 +0,0 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<clangFormatSettings>
|
||||
<option name="ENABLED" value="true" />
|
||||
</clangFormatSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
5
.idea/codeStyles/codeStyleConfig.xml
generated
|
|
@ -1,5 +0,0 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
||||
4
.idea/misc.xml
generated
4
.idea/misc.xml
generated
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
||||
2
.idea/modules.xml
generated
2
.idea/modules.xml
generated
|
|
@ -2,7 +2,7 @@
|
|||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/OrcaSlicer.iml" filepath="$PROJECT_DIR$/.idea/OrcaSlicer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/OrcaSlicer-bambulab.iml" filepath="$PROJECT_DIR$/.idea/OrcaSlicer-bambulab.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -44,3 +44,49 @@ if (UNIX AND NOT APPLE)
|
|||
RUNTIME DESTINATION "."
|
||||
)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
set(PJARCZAK_MAC_WRAPPER_SCRIPT_SOURCE ${CMAKE_SOURCE_DIR}/tools/pjarczak_bambu_macos_linux_wrapper/pjarczak_bambu_macos_linux_wrapper.sh)
|
||||
add_custom_command(TARGET pjarczak_bambu_networking_bridge POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${PJARCZAK_MAC_WRAPPER_SCRIPT_SOURCE}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/pjarczak_bambu_macos_linux_wrapper.sh
|
||||
)
|
||||
install(FILES ${PJARCZAK_MAC_WRAPPER_SCRIPT_SOURCE}
|
||||
DESTINATION "."
|
||||
RENAME pjarczak_bambu_macos_linux_wrapper.sh
|
||||
)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
set(PJARCZAK_WSL_HELPER_SOURCE ${CMAKE_SOURCE_DIR}/tools/pjarczak_bambu_runtime/wsl/pjarczak_wsl_run_host.sh)
|
||||
set(PJARCZAK_WSL_INSTALLER_SOURCE ${CMAKE_SOURCE_DIR}/tools/pjarczak_bambu_runtime/wsl/install_runtime.ps1)
|
||||
set(PJARCZAK_WSL_INSTALLER_CMD_SOURCE ${CMAKE_SOURCE_DIR}/tools/pjarczak_bambu_runtime/wsl/install_runtime.cmd)
|
||||
set(PJARCZAK_WSL_VERIFY_SOURCE ${CMAKE_SOURCE_DIR}/tools/pjarczak_bambu_runtime/wsl/verify_runtime.ps1)
|
||||
set(PJARCZAK_RUNTIME_README_SOURCE ${CMAKE_SOURCE_DIR}/tools/pjarczak_bambu_runtime/README_runtime_bridge.txt)
|
||||
add_custom_command(TARGET pjarczak_bambu_networking_bridge POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${PJARCZAK_WSL_HELPER_SOURCE}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/pjarczak_wsl_run_host.sh
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${PJARCZAK_WSL_INSTALLER_SOURCE}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/install_runtime.ps1
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${PJARCZAK_WSL_INSTALLER_CMD_SOURCE}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/install_runtime.cmd
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${PJARCZAK_WSL_VERIFY_SOURCE}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/verify_runtime.ps1
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${PJARCZAK_RUNTIME_README_SOURCE}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/README_runtime_bridge.txt
|
||||
)
|
||||
install(FILES
|
||||
${PJARCZAK_WSL_HELPER_SOURCE}
|
||||
${PJARCZAK_WSL_INSTALLER_SOURCE}
|
||||
${PJARCZAK_WSL_INSTALLER_CMD_SOURCE}
|
||||
${PJARCZAK_WSL_VERIFY_SOURCE}
|
||||
${PJARCZAK_RUNTIME_README_SOURCE}
|
||||
DESTINATION "."
|
||||
)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
|
@ -39,7 +40,7 @@ bool expected_machine_matches(std::uint16_t machine)
|
|||
{
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
return machine == EM_X86_64;
|
||||
#elif defined(__aarch64__)
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
return machine == EM_AARCH64;
|
||||
#else
|
||||
(void)machine;
|
||||
|
|
@ -60,6 +61,17 @@ std::string env_or(const char* name, const char* fallback)
|
|||
return fallback;
|
||||
}
|
||||
|
||||
bool env_flag_enabled(const char* name)
|
||||
{
|
||||
const char* v = std::getenv(name);
|
||||
if (!v || !*v)
|
||||
return false;
|
||||
std::string s(v);
|
||||
for (char& ch : s)
|
||||
ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
|
||||
return s == "1" || s == "true" || s == "yes" || s == "on";
|
||||
}
|
||||
|
||||
boost::filesystem::path process_dir_path()
|
||||
{
|
||||
try {
|
||||
|
|
@ -83,16 +95,26 @@ const nlohmann::json* find_manifest_entry(const nlohmann::json& root, const std:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool enabled()
|
||||
{
|
||||
if (env_flag_enabled("PJARCZAK_DISABLE_LINUX_BRIDGE"))
|
||||
return false;
|
||||
if (env_flag_enabled("PJARCZAK_FORCE_LINUX_BRIDGE"))
|
||||
return true;
|
||||
#if defined(_MSC_VER) || defined(_WIN32)
|
||||
return true;
|
||||
#elif defined(__WXMAC__) || defined(__APPLE__)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool source_module_is_network_module()
|
||||
{
|
||||
return true;
|
||||
return enabled();
|
||||
}
|
||||
|
||||
bool should_force_linux_plugin_payload(const std::string& plugin_name)
|
||||
|
|
@ -354,4 +376,4 @@ std::vector<std::string> ota_copy_extensions()
|
|||
return {".so", ".json"};
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Slic3r::PJarczakLinuxBridge
|
||||
|
|
|
|||
|
|
@ -7,18 +7,38 @@ namespace Slic3r::PJarczakLinuxBridge {
|
|||
|
||||
namespace {
|
||||
|
||||
const char* env_host_cmd()
|
||||
const char* env_value(const char* name)
|
||||
{
|
||||
return std::getenv("PJARCZAK_LINUX_HOST_CMD");
|
||||
return std::getenv(name);
|
||||
}
|
||||
|
||||
std::string wrapper_executable_name()
|
||||
std::string env_or(const char* name, const char* fallback)
|
||||
{
|
||||
return "pjarczak-bambu-linux-host-wrapper";
|
||||
if (const char* v = env_value(name); v && *v)
|
||||
return v;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
std::string shell_quote(const std::string& value)
|
||||
{
|
||||
std::string out = "'";
|
||||
for (char ch : value) {
|
||||
if (ch == '\'')
|
||||
out += "'\\''";
|
||||
else
|
||||
out += ch;
|
||||
}
|
||||
out += "'";
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string wrapper_script_name()
|
||||
{
|
||||
return "pjarczak_bambu_macos_linux_wrapper.sh";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string host_executable_name()
|
||||
{
|
||||
return "pjarczak_bambu_linux_host";
|
||||
|
|
@ -32,15 +52,31 @@ std::string host_pipe_hint()
|
|||
LaunchSpec build_default_launch_spec()
|
||||
{
|
||||
LaunchSpec spec;
|
||||
if (const char* cmd = env_host_cmd(); cmd && *cmd) {
|
||||
spec.description = "mac via PJARCZAK_LINUX_HOST_CMD";
|
||||
if (const char* cmd = env_value("PJARCZAK_MAC_LINUX_WRAPPER_CMD"); cmd && *cmd) {
|
||||
spec.description = "mac via PJARCZAK_MAC_LINUX_WRAPPER_CMD";
|
||||
spec.argv = {"/bin/sh", "-lc", cmd};
|
||||
return spec;
|
||||
}
|
||||
|
||||
spec.description = "mac via bundled linux wrapper";
|
||||
spec.argv = {sibling_binary_path(wrapper_executable_name()), sibling_binary_path(host_executable_name())};
|
||||
const std::string wrapper = sibling_binary_path(wrapper_script_name());
|
||||
const std::string host = sibling_binary_path(host_executable_name());
|
||||
const std::string runtime_dir_default = sibling_binary_path("pjarczak_bambu_linux_host.runtime");
|
||||
const std::string runtime_dir = env_or("PJARCZAK_MAC_RUNTIME_DIR", runtime_dir_default.c_str());
|
||||
const std::string plugin_dir = env_or("PJARCZAK_BAMBU_PLUGIN_DIR", "");
|
||||
|
||||
std::string cmd;
|
||||
cmd += "exec ";
|
||||
cmd += shell_quote(wrapper);
|
||||
cmd += " ";
|
||||
cmd += shell_quote(host);
|
||||
cmd += " ";
|
||||
cmd += shell_quote(runtime_dir);
|
||||
cmd += " ";
|
||||
cmd += shell_quote(plugin_dir);
|
||||
|
||||
spec.description = "mac via wrapper script";
|
||||
spec.argv = {"/bin/sh", "-lc", cmd};
|
||||
return spec;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Slic3r::PJarczakLinuxBridge
|
||||
|
|
|
|||
|
|
@ -15,9 +15,11 @@ const char* env_value(const char* name)
|
|||
return std::getenv(name);
|
||||
}
|
||||
|
||||
const char* env_host_cmd()
|
||||
std::string env_or(const char* name, const char* fallback)
|
||||
{
|
||||
return env_value("PJARCZAK_LINUX_HOST_CMD");
|
||||
if (const char* v = env_value(name); v && *v)
|
||||
return v;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
std::string shell_quote(const std::string& value)
|
||||
|
|
@ -43,6 +45,31 @@ std::string to_wsl_path(std::string path)
|
|||
return path;
|
||||
}
|
||||
|
||||
std::string host_path_in_distro()
|
||||
{
|
||||
return env_or("PJARCZAK_WSL_HOST_PATH", "/opt/pjarczak/bin/pjarczak_bambu_linux_host");
|
||||
}
|
||||
|
||||
std::string runtime_dir_in_distro()
|
||||
{
|
||||
return env_or("PJARCZAK_WSL_RUNTIME_DIR", "/opt/pjarczak/runtime");
|
||||
}
|
||||
|
||||
std::string wsl_distro_name()
|
||||
{
|
||||
return env_or("PJARCZAK_WSL_DISTRO", "PJARCZAK-BAMBU");
|
||||
}
|
||||
|
||||
std::string wsl_user_name()
|
||||
{
|
||||
return env_or("PJARCZAK_WSL_USER", "root");
|
||||
}
|
||||
|
||||
std::string wsl_shell_path()
|
||||
{
|
||||
return env_or("PJARCZAK_WSL_SHELL", "/bin/sh");
|
||||
}
|
||||
|
||||
void append_shell_export(std::string& script, const char* name, const std::string& value)
|
||||
{
|
||||
if (value.empty())
|
||||
|
|
@ -62,14 +89,10 @@ void append_shell_path_export(std::string& script, const char* name)
|
|||
append_shell_export(script, name, to_wsl_path(value));
|
||||
}
|
||||
|
||||
std::string host_runtime_dir_name()
|
||||
{
|
||||
return "pjarczak_bambu_linux_host.runtime";
|
||||
}
|
||||
|
||||
std::string build_shell_prefix()
|
||||
{
|
||||
std::string script = "set -eu;";
|
||||
|
||||
append_shell_path_export(script, "PJARCZAK_BAMBU_PLUGIN_DIR");
|
||||
append_shell_path_export(script, "PJARCZAK_BAMBU_NETWORK_SO");
|
||||
append_shell_path_export(script, "PJARCZAK_BAMBU_SOURCE_SO");
|
||||
|
|
@ -78,15 +101,36 @@ std::string build_shell_prefix()
|
|||
if (const char* version = env_value("PJARCZAK_EXPECTED_BAMBU_NETWORK_VERSION"); version && *version)
|
||||
append_shell_export(script, "PJARCZAK_EXPECTED_BAMBU_NETWORK_VERSION", version);
|
||||
|
||||
const std::string runtime_path = to_wsl_path(sibling_binary_path(host_runtime_dir_name()));
|
||||
script += "export LD_LIBRARY_PATH=";
|
||||
script += shell_quote(runtime_path);
|
||||
script += "${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}};";
|
||||
script += "RUNTIME_DIR=";
|
||||
script += shell_quote(runtime_dir_in_distro());
|
||||
script += ";";
|
||||
script += "HOST=";
|
||||
script += shell_quote(host_path_in_distro());
|
||||
script += ";";
|
||||
script += "PLUGIN_DIR=${PJARCZAK_BAMBU_PLUGIN_DIR:-};";
|
||||
script += "if [ -z \"${PJARCZAK_BAMBU_NETWORK_SO:-}\" ] && [ -n \"$PLUGIN_DIR\" ]; then export PJARCZAK_BAMBU_NETWORK_SO=\"$PLUGIN_DIR/libbambu_networking.so\"; fi;";
|
||||
script += "if [ -z \"${PJARCZAK_BAMBU_SOURCE_SO:-}\" ] && [ -n \"$PLUGIN_DIR\" ]; then export PJARCZAK_BAMBU_SOURCE_SO=\"$PLUGIN_DIR/libBambuSource.so\"; fi;";
|
||||
script += "if [ -z \"${PJARCZAK_BAMBU_LIVE555_SO:-}\" ] && [ -n \"$PLUGIN_DIR\" ]; then export PJARCZAK_BAMBU_LIVE555_SO=\"$PLUGIN_DIR/liblive555.so\"; fi;";
|
||||
script += "LIB_DIR=\"$RUNTIME_DIR\";";
|
||||
script += "if [ -n \"${PJARCZAK_BAMBU_NETWORK_SO:-}\" ]; then LIB_DIR=$(dirname \"$PJARCZAK_BAMBU_NETWORK_SO\"); fi;";
|
||||
script += "export LD_LIBRARY_PATH=\"$LIB_DIR:$RUNTIME_DIR${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}\";";
|
||||
script += "[ -x \"$HOST\" ] || chmod +x \"$HOST\" || true;";
|
||||
script += "[ -x \"$HOST\" ] || { echo \"missing linux host: $HOST\" 1>&2; exit 127; };";
|
||||
script += "if [ -n \"${PJARCZAK_BAMBU_NETWORK_SO:-}\" ] && [ ! -f \"$PJARCZAK_BAMBU_NETWORK_SO\" ]; then echo \"missing libbambu_networking.so: $PJARCZAK_BAMBU_NETWORK_SO\" 1>&2; exit 127; fi;";
|
||||
script += "if [ -n \"${PJARCZAK_BAMBU_SOURCE_SO:-}\" ] && [ ! -f \"$PJARCZAK_BAMBU_SOURCE_SO\" ]; then echo \"missing libBambuSource.so: $PJARCZAK_BAMBU_SOURCE_SO\" 1>&2; exit 127; fi;";
|
||||
script += "if [ -n \"${PJARCZAK_BAMBU_LIVE555_SO:-}\" ] && [ ! -f \"$PJARCZAK_BAMBU_LIVE555_SO\" ]; then echo \"missing liblive555.so: $PJARCZAK_BAMBU_LIVE555_SO\" 1>&2; exit 127; fi;";
|
||||
return script;
|
||||
}
|
||||
|
||||
std::string build_default_shell_script()
|
||||
{
|
||||
std::string script = build_shell_prefix();
|
||||
script += "exec \"$HOST\";";
|
||||
return script;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string host_executable_name()
|
||||
{
|
||||
return "pjarczak_bambu_linux_host";
|
||||
|
|
@ -100,26 +144,30 @@ std::string host_pipe_hint()
|
|||
LaunchSpec build_default_launch_spec()
|
||||
{
|
||||
LaunchSpec spec;
|
||||
std::string script = build_shell_prefix();
|
||||
|
||||
if (const char* cmd = env_host_cmd(); cmd && *cmd) {
|
||||
if (const char* cmd = env_value("PJARCZAK_LINUX_HOST_CMD"); cmd && *cmd) {
|
||||
spec.description = "windows via PJARCZAK_LINUX_HOST_CMD";
|
||||
std::string script = build_shell_prefix();
|
||||
script += cmd;
|
||||
spec.argv = {"wsl.exe", "--", "bash", "-lc", script};
|
||||
spec.argv = {
|
||||
"wsl.exe",
|
||||
"--distribution", wsl_distro_name(),
|
||||
"--user", wsl_user_name(),
|
||||
"--exec", wsl_shell_path(),
|
||||
"-lc", script
|
||||
};
|
||||
return spec;
|
||||
}
|
||||
|
||||
const std::string host_path = to_wsl_path(sibling_binary_path(host_executable_name()));
|
||||
|
||||
script += "HOST=";
|
||||
script += shell_quote(host_path);
|
||||
script += ";";
|
||||
script += "[ -x \"$HOST\" ] || chmod +x \"$HOST\" || true;";
|
||||
script += "exec \"$HOST\";";
|
||||
|
||||
spec.description = "windows via WSL";
|
||||
spec.argv = {"wsl.exe", "--", "bash", "-lc", script};
|
||||
spec.description = "windows via WSL distro=" + wsl_distro_name() + " user=" + wsl_user_name();
|
||||
spec.argv = {
|
||||
"wsl.exe",
|
||||
"--distribution", wsl_distro_name(),
|
||||
"--user", wsl_user_name(),
|
||||
"--exec", wsl_shell_path(),
|
||||
"-lc", build_default_shell_script()
|
||||
};
|
||||
return spec;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Slic3r::PJarczakLinuxBridge
|
||||
|
|
|
|||
|
|
@ -21,17 +21,40 @@ RpcClient::~RpcClient()
|
|||
stop_locked();
|
||||
}
|
||||
|
||||
void RpcClient::append_stderr_line(const std::string& line)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_stderr_mutex);
|
||||
if (!m_stderr_tail.empty())
|
||||
m_stderr_tail += "\n";
|
||||
m_stderr_tail += line;
|
||||
constexpr std::size_t max_tail = 8192;
|
||||
if (m_stderr_tail.size() > max_tail)
|
||||
m_stderr_tail.erase(0, m_stderr_tail.size() - max_tail);
|
||||
}
|
||||
|
||||
std::string RpcClient::stderr_summary() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_stderr_mutex);
|
||||
return m_stderr_tail;
|
||||
}
|
||||
|
||||
bool RpcClient::start_locked()
|
||||
{
|
||||
if (m_proc && m_proc->child.running())
|
||||
return true;
|
||||
|
||||
auto spec = build_default_launch_spec();
|
||||
try {
|
||||
auto spec = build_default_launch_spec();
|
||||
if (spec.argv.empty()) {
|
||||
m_last_error = "empty launch spec";
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_stderr_mutex);
|
||||
m_stderr_tail.clear();
|
||||
}
|
||||
|
||||
bp::environment env = boost::this_process::environment();
|
||||
for (const auto& kv : spec.env)
|
||||
env[kv.first] = kv.second;
|
||||
|
|
@ -44,21 +67,24 @@ bool RpcClient::start_locked()
|
|||
if (!exe_path.is_absolute())
|
||||
exe_path = bp::search_path(spec.argv[0]);
|
||||
if (exe_path.empty()) {
|
||||
m_last_error = "bridge host executable not found: " + spec.argv[0];
|
||||
m_last_error = "bridge host executable not found for " + spec.description + ": " + spec.argv[0];
|
||||
return false;
|
||||
}
|
||||
|
||||
auto proc = std::make_unique<Proc>();
|
||||
proc->child = bp::child(exe_path, bp::args(args), bp::std_in < proc->in, bp::std_out > proc->out, env);
|
||||
proc->child = bp::child(exe_path, bp::args(args), bp::std_in < proc->in, bp::std_out > proc->out, bp::std_err > proc->err, env);
|
||||
m_proc = std::move(proc);
|
||||
m_reader_stop = false;
|
||||
if (m_reader.joinable())
|
||||
m_reader.join();
|
||||
if (m_stderr_reader.joinable())
|
||||
m_stderr_reader.join();
|
||||
m_reader = std::thread([this] { reader_loop(); });
|
||||
m_stderr_reader = std::thread([this] { stderr_reader_loop(); });
|
||||
m_last_error.clear();
|
||||
return true;
|
||||
} catch (const std::exception& e) {
|
||||
m_last_error = e.what();
|
||||
m_last_error = "bridge host start failed (" + spec.description + "): " + e.what();
|
||||
m_proc.reset();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -75,6 +101,8 @@ void RpcClient::stop_locked()
|
|||
}
|
||||
if (m_reader.joinable())
|
||||
m_reader.join();
|
||||
if (m_stderr_reader.joinable())
|
||||
m_stderr_reader.join();
|
||||
m_proc.reset();
|
||||
}
|
||||
|
||||
|
|
@ -90,26 +118,53 @@ bool RpcClient::is_started() const
|
|||
return m_proc && m_proc->child.running();
|
||||
}
|
||||
|
||||
void RpcClient::reader_loop()
|
||||
void RpcClient::stderr_reader_loop()
|
||||
{
|
||||
while (!m_reader_stop) {
|
||||
std::string line;
|
||||
for (;;) {
|
||||
Proc* proc = nullptr;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_state_mutex);
|
||||
if (!m_proc)
|
||||
break;
|
||||
if (!std::getline(m_proc->out, line)) {
|
||||
m_last_error = "bridge host closed stdout";
|
||||
auto pending = m_pending;
|
||||
m_pending.clear();
|
||||
for (auto& it : pending) {
|
||||
std::lock_guard<std::mutex> plock(it.second->mutex);
|
||||
it.second->payload = {{"ok", false}, {"error", m_last_error}};
|
||||
it.second->ready = true;
|
||||
it.second->cv.notify_all();
|
||||
}
|
||||
proc = m_proc.get();
|
||||
}
|
||||
|
||||
std::string line;
|
||||
if (!std::getline(proc->err, line))
|
||||
break;
|
||||
if (!line.empty())
|
||||
append_stderr_line(line);
|
||||
}
|
||||
}
|
||||
|
||||
void RpcClient::reader_loop()
|
||||
{
|
||||
for (;;) {
|
||||
Proc* proc = nullptr;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_state_mutex);
|
||||
if (!m_proc)
|
||||
break;
|
||||
proc = m_proc.get();
|
||||
}
|
||||
|
||||
std::string line;
|
||||
if (!std::getline(proc->out, line)) {
|
||||
std::string error = "bridge host closed stdout";
|
||||
const std::string stderr = stderr_summary();
|
||||
if (!stderr.empty())
|
||||
error += "; stderr: " + stderr;
|
||||
std::lock_guard<std::mutex> lock(m_state_mutex);
|
||||
m_last_error = error;
|
||||
auto pending = m_pending;
|
||||
m_pending.clear();
|
||||
for (auto& it : pending) {
|
||||
std::lock_guard<std::mutex> plock(it.second->mutex);
|
||||
it.second->payload = {{"ok", false}, {"error", m_last_error}};
|
||||
it.second->ready = true;
|
||||
it.second->cv.notify_all();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
RpcFrame reply;
|
||||
|
|
@ -209,4 +264,4 @@ std::string RpcClient::last_error() const
|
|||
return m_last_error;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Slic3r::PJarczakLinuxBridge
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ private:
|
|||
struct Proc {
|
||||
boost::process::opstream in;
|
||||
boost::process::ipstream out;
|
||||
boost::process::ipstream err;
|
||||
boost::process::child child;
|
||||
};
|
||||
|
||||
|
|
@ -47,15 +48,21 @@ private:
|
|||
bool start_locked();
|
||||
void stop_locked();
|
||||
void reader_loop();
|
||||
void stderr_reader_loop();
|
||||
void append_stderr_line(const std::string& line);
|
||||
std::string stderr_summary() const;
|
||||
|
||||
mutable std::mutex m_state_mutex;
|
||||
std::mutex m_write_mutex;
|
||||
std::mutex m_stderr_mutex;
|
||||
std::unique_ptr<Proc> m_proc;
|
||||
std::thread m_reader;
|
||||
std::thread m_stderr_reader;
|
||||
int m_next_id{1};
|
||||
std::string m_last_error;
|
||||
std::map<int, std::shared_ptr<Pending>> m_pending;
|
||||
bool m_reader_stop{false};
|
||||
std::string m_stderr_tail;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
HOST_PATH="${1:-}"
|
||||
RUNTIME_DIR="${2:-}"
|
||||
PLUGIN_DIR="${3:-}"
|
||||
|
||||
if [ -n "${PJARCZAK_MAC_LINUX_WRAPPER_CMD:-}" ]; then
|
||||
exec /bin/sh -lc "$PJARCZAK_MAC_LINUX_WRAPPER_CMD"
|
||||
fi
|
||||
|
||||
if [ -n "${PJARCZAK_MAC_DOCKER_IMAGE:-}" ]; then
|
||||
exec docker run --rm -i \
|
||||
-e PJARCZAK_BAMBU_PLUGIN_DIR=/runtime/plugin \
|
||||
-e PJARCZAK_BAMBU_NETWORK_SO=/runtime/plugin/libbambu_networking.so \
|
||||
-e PJARCZAK_BAMBU_SOURCE_SO=/runtime/plugin/libBambuSource.so \
|
||||
-e PJARCZAK_BAMBU_LIVE555_SO=/runtime/plugin/liblive555.so \
|
||||
-e PJARCZAK_EXPECTED_BAMBU_NETWORK_VERSION="${PJARCZAK_EXPECTED_BAMBU_NETWORK_VERSION:-}" \
|
||||
-v "$RUNTIME_DIR:/runtime/host:ro" \
|
||||
-v "$PLUGIN_DIR:/runtime/plugin:ro" \
|
||||
"$PJARCZAK_MAC_DOCKER_IMAGE" /runtime/host/pjarczak_bambu_linux_host
|
||||
fi
|
||||
|
||||
if [ -n "${PJARCZAK_MAC_LIMA_INSTANCE:-}" ]; then
|
||||
exec limactl shell "$PJARCZAK_MAC_LIMA_INSTANCE" -- /bin/sh -lc \
|
||||
"export PJARCZAK_BAMBU_PLUGIN_DIR=$(printf %s \"$PLUGIN_DIR\"); export PJARCZAK_BAMBU_NETWORK_SO=$(printf %s \"$PLUGIN_DIR/libbambu_networking.so\"); export PJARCZAK_BAMBU_SOURCE_SO=$(printf %s \"$PLUGIN_DIR/libBambuSource.so\"); export PJARCZAK_BAMBU_LIVE555_SO=$(printf %s \"$PLUGIN_DIR/liblive555.so\"); exec $(printf %s \"$HOST_PATH\")"
|
||||
fi
|
||||
|
||||
echo "No macOS Linux wrapper configured. Set PJARCZAK_MAC_LINUX_WRAPPER_CMD, PJARCZAK_MAC_DOCKER_IMAGE or PJARCZAK_MAC_LIMA_INSTANCE." >&2
|
||||
exit 127
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
param(
|
||||
[Parameter(Mandatory = $true)][string]$OutputDir,
|
||||
[Parameter(Mandatory = $true)][string]$RootFs,
|
||||
[Parameter(Mandatory = $true)][string]$LinuxHostBinary,
|
||||
[string]$RuntimeDir = ""
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$scriptDir = Split-Path -Parent $PSCommandPath
|
||||
$toolsRoot = [System.IO.Path]::GetFullPath((Join-Path $scriptDir '..'))
|
||||
$wslRoot = Join-Path $toolsRoot 'wsl'
|
||||
|
||||
if (-not (Test-Path $RootFs)) { throw "RootFs not found: $RootFs" }
|
||||
if (-not (Test-Path $LinuxHostBinary)) { throw "LinuxHostBinary not found: $LinuxHostBinary" }
|
||||
if ($RuntimeDir -and -not (Test-Path $RuntimeDir)) { throw "RuntimeDir not found: $RuntimeDir" }
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $OutputDir | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $OutputDir 'rootfs') | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $OutputDir 'linux-runtime') | Out-Null
|
||||
|
||||
Copy-Item -Force (Join-Path $wslRoot 'install_runtime.ps1') (Join-Path $OutputDir 'install_runtime.ps1')
|
||||
Copy-Item -Force (Join-Path $wslRoot 'install_runtime.cmd') (Join-Path $OutputDir 'install_runtime.cmd')
|
||||
Copy-Item -Force (Join-Path $wslRoot 'verify_runtime.ps1') (Join-Path $OutputDir 'verify_runtime.ps1')
|
||||
Copy-Item -Force (Join-Path $toolsRoot 'README_runtime_bridge.txt') (Join-Path $OutputDir 'README_runtime_bridge.txt')
|
||||
Copy-Item -Force $RootFs (Join-Path $OutputDir 'rootfs\pjarczak-bambu-rootfs.tar')
|
||||
Copy-Item -Force $LinuxHostBinary (Join-Path $OutputDir 'linux-runtime\pjarczak_bambu_linux_host')
|
||||
|
||||
if ($RuntimeDir) {
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $OutputDir 'linux-runtime\runtime') | Out-Null
|
||||
Copy-Item -Recurse -Force (Join-Path $RuntimeDir '*') (Join-Path $OutputDir 'linux-runtime\runtime')
|
||||
}
|
||||
|
||||
Write-Host 'Bundle created:'
|
||||
Write-Host $OutputDir
|
||||
25
tools/pjarczak_bambu_runtime/wsl/pjarczak_wsl_run_host.sh
Normal file
25
tools/pjarczak_bambu_runtime/wsl/pjarczak_wsl_run_host.sh
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
HOST="${1:-${PJARCZAK_WSL_HOST_PATH:-/opt/pjarczak/bin/pjarczak_bambu_linux_host}}"
|
||||
RUNTIME_DIR="${2:-${PJARCZAK_WSL_RUNTIME_DIR:-/opt/pjarczak/runtime}}"
|
||||
PLUGIN_DIR="${PJARCZAK_BAMBU_PLUGIN_DIR:-}"
|
||||
|
||||
if [ -z "${PJARCZAK_BAMBU_NETWORK_SO:-}" ] && [ -n "$PLUGIN_DIR" ]; then
|
||||
export PJARCZAK_BAMBU_NETWORK_SO="$PLUGIN_DIR/libbambu_networking.so"
|
||||
fi
|
||||
if [ -z "${PJARCZAK_BAMBU_SOURCE_SO:-}" ] && [ -n "$PLUGIN_DIR" ]; then
|
||||
export PJARCZAK_BAMBU_SOURCE_SO="$PLUGIN_DIR/libBambuSource.so"
|
||||
fi
|
||||
if [ -z "${PJARCZAK_BAMBU_LIVE555_SO:-}" ] && [ -n "$PLUGIN_DIR" ]; then
|
||||
export PJARCZAK_BAMBU_LIVE555_SO="$PLUGIN_DIR/liblive555.so"
|
||||
fi
|
||||
|
||||
LIB_DIR="$RUNTIME_DIR"
|
||||
if [ -n "${PJARCZAK_BAMBU_NETWORK_SO:-}" ]; then
|
||||
LIB_DIR="$(dirname "$PJARCZAK_BAMBU_NETWORK_SO")"
|
||||
fi
|
||||
|
||||
export LD_LIBRARY_PATH="$LIB_DIR:$RUNTIME_DIR${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
|
||||
[ -x "$HOST" ] || chmod +x "$HOST" || true
|
||||
exec "$HOST"
|
||||
75
tools/pjarczak_bambu_runtime/wsl/verify_runtime.ps1
Normal file
75
tools/pjarczak_bambu_runtime/wsl/verify_runtime.ps1
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
param(
|
||||
[string]$Distro = $(if ($env:PJARCZAK_WSL_DISTRO) { $env:PJARCZAK_WSL_DISTRO } else { 'PJARCZAK-BAMBU' })
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function Find-WslExe {
|
||||
foreach ($candidate in @((Join-Path $env:WINDIR 'System32\wsl.exe'), (Join-Path $env:WINDIR 'Sysnative\wsl.exe'))) {
|
||||
if (Test-Path $candidate) {
|
||||
return $candidate
|
||||
}
|
||||
}
|
||||
$cmd = Get-Command wsl.exe -ErrorAction SilentlyContinue
|
||||
if ($cmd) {
|
||||
return $cmd.Source
|
||||
}
|
||||
throw 'wsl.exe not found'
|
||||
}
|
||||
|
||||
function Step([string]$Name, [scriptblock]$Block) {
|
||||
Write-Host ('[' + $Name + ']')
|
||||
$global:LASTEXITCODE = 0
|
||||
& $Block
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "$Name failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
Write-Host ''
|
||||
}
|
||||
|
||||
function Step-WslLddStrict([string]$Name, [string]$CommandText) {
|
||||
Step $Name {
|
||||
$output = & $WslExe --distribution $Distro --user root --exec /bin/sh -lc $CommandText 2>&1
|
||||
$exitCode = $LASTEXITCODE
|
||||
$text = ($output | Out-String)
|
||||
$text = $text.TrimEnd()
|
||||
if (-not [string]::IsNullOrWhiteSpace($text)) {
|
||||
Write-Host $text
|
||||
}
|
||||
if ($exitCode -ne 0) {
|
||||
throw "$Name failed with exit code $exitCode"
|
||||
}
|
||||
if ($text -match '(?m)\bnot found\b') {
|
||||
throw "$Name reported missing shared libraries"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$WslExe = Find-WslExe
|
||||
|
||||
Step 'env' {
|
||||
Write-Host ('PJARCZAK_WSL_DISTRO=' + $env:PJARCZAK_WSL_DISTRO)
|
||||
Write-Host ('PJARCZAK_WSL_USER=' + $env:PJARCZAK_WSL_USER)
|
||||
Write-Host ('PJARCZAK_WSL_HOST_PATH=' + $env:PJARCZAK_WSL_HOST_PATH)
|
||||
Write-Host ('PJARCZAK_WSL_RUNTIME_DIR=' + $env:PJARCZAK_WSL_RUNTIME_DIR)
|
||||
}
|
||||
|
||||
Step 'wsl-status' {
|
||||
& $WslExe --status
|
||||
}
|
||||
|
||||
Step 'wsl-list' {
|
||||
& $WslExe -l -v
|
||||
}
|
||||
|
||||
Step 'host-check' {
|
||||
& $WslExe --distribution $Distro --user root --exec /bin/sh -lc 'set -eu; test -x /opt/pjarczak/bin/pjarczak_bambu_linux_host; echo HOST_OK'
|
||||
}
|
||||
|
||||
Step 'runtime-check' {
|
||||
& $WslExe --distribution $Distro --user root --exec /bin/sh -lc 'set -eu; ls -la /opt/pjarczak/bin; ls -la /opt/pjarczak/runtime || true'
|
||||
}
|
||||
|
||||
Step-WslLddStrict 'ldd' 'set -eu; LD_LIBRARY_PATH=/opt/pjarczak/runtime ldd /opt/pjarczak/bin/pjarczak_bambu_linux_host'
|
||||
|
||||
Write-Host 'Verify finished.'
|
||||
Loading…
Add table
Reference in a new issue