From 2a169a92423964d05a27b1c11fd0ae17d4b688af Mon Sep 17 00:00:00 2001 From: Matthew Asplund Date: Sat, 18 Jan 2025 16:30:26 -0600 Subject: [PATCH] Linux Soup View (#296) * Get view working on linux * Fix paths * Fix open flags for linux monitor --- .vscode/launch.json | 11 ++++++++++ code/client/cli/source/Program.h | 2 +- .../client/cli/source/commands/BuildCommand.h | 6 +++--- code/client/cli/source/commands/ViewCommand.h | 6 +++++- .../core/source/build/BuildLoadEngine.h | 2 +- code/client/tools/Public.cpp | 20 ++++++++++++------ code/generate-sharp/soup-view/SoupView.csproj | 21 ++++++++++++------- .../soup-view/properties/launchSettings.json | 3 ++- .../view-models/OperationGraphViewModel.cs | 16 +++++++++++++- .../view-models/TaskGraphViewModel.cs | 16 +++++++++++++- .../host/linux/LinuxSystemAccessMonitor.h | 18 ++++++++-------- docs/cli/run.md | 2 +- docs/cli/target.md | 2 +- scripts/linux/build | 4 ++++ scripts/linux/build-client | 4 ++++ scripts/linux/build-tools | 11 +++++++--- scripts/linux/build-view | 6 +++++- scripts/windows/build-client.cmd | 5 +++++ scripts/windows/build-tools.cmd | 5 +++++ 19 files changed, 123 insertions(+), 37 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 5d847a2c..f2ec9463 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,6 +12,17 @@ "stopAtEntry": false, "console": "internalConsole" }, + { + "name": "Debug Soup View", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "", + "program": "${workspaceFolder}/out/msbuild/bin/SoupView/Debug/net9.0/linux-x64/SoupView.dll", + "args": [ "${workspaceFolder}/code/client/cli/Recipe.sml" ], + "cwd": "${workspaceFolder}/out/run", + "stopAtEntry": false, + "console": "internalConsole" + }, { "name": "Debug Soup", "type": "cppdbg", diff --git a/code/client/cli/source/Program.h b/code/client/cli/source/Program.h index b3cd507d..1f935eb2 100644 --- a/code/client/cli/source/Program.h +++ b/code/client/cli/source/Program.h @@ -61,7 +61,7 @@ namespace Soup::Client System::IProcessManager::Register(std::make_shared()); Monitor::IMonitorProcessManager::Register(std::make_shared()); #else - #error "Unknown Platform" + #error "Unknown Platform" #endif IO::IConsoleManager::Register(std::make_shared()); diff --git a/code/client/cli/source/commands/BuildCommand.h b/code/client/cli/source/commands/BuildCommand.h index 07663651..5dbeaed7 100644 --- a/code/client/cli/source/commands/BuildCommand.h +++ b/code/client/cli/source/commands/BuildCommand.h @@ -59,11 +59,11 @@ namespace Soup::Client // Platform specific defaults #if defined(_WIN32) - arguments.HostPlatform = "Windows"; + arguments.HostPlatform = "Windows"; #elif defined(__linux__) - arguments.HostPlatform = "Linux"; + arguments.HostPlatform = "Linux"; #else - #error "Unknown Platform" + #error "Unknown Platform" #endif // Process well known parameters diff --git a/code/client/cli/source/commands/ViewCommand.h b/code/client/cli/source/commands/ViewCommand.h index 014708dc..4c093e93 100644 --- a/code/client/cli/source/commands/ViewCommand.h +++ b/code/client/cli/source/commands/ViewCommand.h @@ -66,13 +66,17 @@ namespace Soup::Client #error "Unknown platform" #endif + // Find the folder root + auto processFilename = System::IProcessManager::Current().GetCurrentProcessFileName(); + auto processDirectory = processFilename.GetParent(); + // Execute the requested target Log::Info("CreateProcess"); Log::Diag(executable.ToString()); auto process = System::IProcessManager::Current().CreateProcess( executable, std::move(arguments), - workingDirectory, + processDirectory, false); process->Start(); process->WaitForExit(); diff --git a/code/client/core/source/build/BuildLoadEngine.h b/code/client/core/source/build/BuildLoadEngine.h index 48903fc5..8a1d1550 100644 --- a/code/client/core/source/build/BuildLoadEngine.h +++ b/code/client/core/source/build/BuildLoadEngine.h @@ -1210,7 +1210,7 @@ namespace Soup::Core Log::HighPriority("The installation may be corrupted"); // Nothing we can do, exit - throw HandledException(1123124); + throw HandledException(1723124); } // Built in packages do not load the lock diff --git a/code/client/tools/Public.cpp b/code/client/tools/Public.cpp index 0c808ea9..98e3f754 100644 --- a/code/client/tools/Public.cpp +++ b/code/client/tools/Public.cpp @@ -1,11 +1,15 @@ // Include all standard library headers in the global module #include +#include #include #include #ifdef _WIN32 #include #define SOUP_TOOLS_API __declspec(dllexport) +#ifdef GetCurrentDirectory +#undef GetCurrentDirectory +#endif #else #define SOUP_TOOLS_API #define CoTaskMemAlloc(p) malloc(p) @@ -88,6 +92,7 @@ std::string LoadBuildGraphContent(const Path& workingDirectory) { // Setup the filter auto defaultTypes = + static_cast(TraceEventFlag::Information) | static_cast(TraceEventFlag::HighPriority) | static_cast(TraceEventFlag::Warning) | static_cast(TraceEventFlag::Error) | @@ -109,14 +114,17 @@ std::string LoadBuildGraphContent(const Path& workingDirectory) auto globalParameters = ValueTable(); + // Find the built in folder root + auto rootDirectory = System::IFileSystem::Current().GetCurrentDirectory(); + auto builtInPackageDirectory = rootDirectory + Path("./BuiltIn/"); + // Load user config state - auto builtInPackageDirectory = Path("C:/Program Files/SoupBuild/Soup/Soup/BuiltIn/"); auto userDataPath = BuildEngine::GetSoupUserDataPath(); auto recipeCache = RecipeCache(); auto packageProvider = BuildEngine::LoadBuildGraph( - builtInPackageDirectory, + builtInPackageDirectory, workingDirectory, globalParameters, userDataPath, @@ -139,18 +147,18 @@ std::string LoadBuildGraphContent(const Path& workingDirectory) auto value = jsonResult.dump(); return value; } - catch (const HandledException&) + catch (const HandledException& ex) { json11::Json jsonResult = json11::Json::object({ - { "Message", "FAILED" }, + { "Message", std::format("HANDLED ERROR: {0}", ex.GetExitCode()) }, { "IsSuccess", false }, }); return jsonResult.dump(); } - catch(const std::exception& e) + catch(const std::exception& ex) { json11::Json jsonResult = json11::Json::object({ - { "Message", e.what() }, + { "Message", ex.what() }, { "IsSuccess", false }, }); return jsonResult.dump(); diff --git a/code/generate-sharp/soup-view/SoupView.csproj b/code/generate-sharp/soup-view/SoupView.csproj index 1bdd5ced..bb8739c4 100644 --- a/code/generate-sharp/soup-view/SoupView.csproj +++ b/code/generate-sharp/soup-view/SoupView.csproj @@ -11,17 +11,24 @@ false true + + OZlIVjblazFuKXg-raWUNoGEnG4 + + + Oltq7cGwk0Rbgy1I-3mCMDDE5yM + + + SoupTools.dll + + + SoupTools.so + - - - PreserveNewest - - - - + + PreserveNewest diff --git a/code/generate-sharp/soup-view/properties/launchSettings.json b/code/generate-sharp/soup-view/properties/launchSettings.json index a429932d..5dfc12aa 100644 --- a/code/generate-sharp/soup-view/properties/launchSettings.json +++ b/code/generate-sharp/soup-view/properties/launchSettings.json @@ -2,7 +2,8 @@ "profiles": { "SoupView": { "commandName": "Project", - "commandLineArgs": "C:\\Users\\mwasp\\Dev\\Repos\\Soup\\Source\\Client\\CLI\\Recipe.sml", + "commandLineArgs": "C:\\Users\\mwasp\\source\\repos\\soup\\code\\client\\cli\\Recipe.sml", + "workingDirectory": "C:\\Users\\mwasp\\source\\repos\\soup\\out\\run\\Soup", "nativeDebugging": true } } diff --git a/code/generate-sharp/soup-view/view-models/OperationGraphViewModel.cs b/code/generate-sharp/soup-view/view-models/OperationGraphViewModel.cs index abc9eeab..2579ceef 100644 --- a/code/generate-sharp/soup-view/view-models/OperationGraphViewModel.cs +++ b/code/generate-sharp/soup-view/view-models/OperationGraphViewModel.cs @@ -151,7 +151,21 @@ private List BuildGraphNodes( private async Task GetTargetPathAsync(Path packageDirectory) { - var processInfo = new ProcessStartInfo("C:\\Program Files\\SoupBuild\\Soup\\Soup\\Soup.exe", $"target {packageDirectory}") + string soupExe; + if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) + { + soupExe = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "Soup.exe"); + } + else if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux)) + { + soupExe = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "soup"); + } + else + { + throw new NotSupportedException("Unknown OS Platform"); + } + + var processInfo = new ProcessStartInfo(soupExe, $"target {packageDirectory}") { RedirectStandardOutput = true, CreateNoWindow = true, diff --git a/code/generate-sharp/soup-view/view-models/TaskGraphViewModel.cs b/code/generate-sharp/soup-view/view-models/TaskGraphViewModel.cs index a482a3b4..38e53b55 100644 --- a/code/generate-sharp/soup-view/view-models/TaskGraphViewModel.cs +++ b/code/generate-sharp/soup-view/view-models/TaskGraphViewModel.cs @@ -207,8 +207,22 @@ private List BuildGraphNodes( private async Task GetTargetPathAsync(Path packageDirectory, string? owner) { + string soupExe; + if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) + { + soupExe = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "Soup.exe"); + } + else if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux)) + { + soupExe = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "soup"); + } + else + { + throw new NotSupportedException("Unknown OS Platform"); + } + var optionalOwnerFlag = owner is null ? string.Empty : $" -owner {owner}"; - var processInfo = new ProcessStartInfo("C:\\Program Files\\SoupBuild\\Soup\\Soup\\Soup.exe", $"target {packageDirectory}{optionalOwnerFlag}") + var processInfo = new ProcessStartInfo(soupExe, $"target {packageDirectory}{optionalOwnerFlag}") { RedirectStandardOutput = true, CreateNoWindow = true, diff --git a/code/monitor/host/linux/LinuxSystemAccessMonitor.h b/code/monitor/host/linux/LinuxSystemAccessMonitor.h index 851f55c6..d608895d 100644 --- a/code/monitor/host/linux/LinuxSystemAccessMonitor.h +++ b/code/monitor/host/linux/LinuxSystemAccessMonitor.h @@ -62,9 +62,9 @@ namespace Monitor::Linux void OnOpen(std::string_view path, int32_t oflag, int32_t result) override final { - bool isWriteOnly = (oflag & O_WRONLY) != 0; - bool isReadWrite = (oflag & O_RDWR) != 0; - bool isReadOnly = (oflag & O_RDONLY) != 0; + bool isWriteOnly = (oflag & O_ACCMODE) == O_WRONLY; + bool isReadWrite = (oflag & O_ACCMODE) == O_RDWR; + bool isReadOnly = (oflag & O_ACCMODE) == O_RDONLY; bool wasBlocked = false; bool exists = result != -1; @@ -84,9 +84,9 @@ namespace Monitor::Linux void OnOpenAt(int32_t dirfd, std::string_view pathname, int32_t flags, int32_t result) override final { - bool isWriteOnly = (flags & O_WRONLY) != 0; - bool isReadWrite = (flags & O_RDWR) != 0; - bool isReadOnly = (flags & O_RDONLY) != 0; + bool isWriteOnly = (flags & O_ACCMODE) == O_WRONLY; + bool isReadWrite = (flags & O_ACCMODE) == O_RDWR; + bool isReadOnly = (flags & O_ACCMODE) == O_RDONLY; bool wasBlocked = false; bool exists = result != -1; @@ -106,9 +106,9 @@ namespace Monitor::Linux void OnOpenAt2(int32_t dirfd, std::string_view pathname, int32_t flags, int32_t result) override final { - bool isWriteOnly = (flags & O_WRONLY) != 0; - bool isReadWrite = (flags & O_RDWR) != 0; - bool isReadOnly = (flags & O_RDONLY) != 0; + bool isWriteOnly = (flags & O_ACCMODE) == O_WRONLY; + bool isReadWrite = (flags & O_ACCMODE) == O_RDWR; + bool isReadOnly = (flags & O_ACCMODE) == O_RDONLY; bool wasBlocked = false; bool exists = result != -1; diff --git a/docs/cli/run.md b/docs/cli/run.md index 1a6f57bf..cc7fa8d9 100644 --- a/docs/cli/run.md +++ b/docs/cli/run.md @@ -19,5 +19,5 @@ soup run Run a release Recipe in a different directory and pass in a single parameter to the child executable. ``` -soup run ./Code/MyProject/ -flavor release -args MyParameter +soup run ./Code/MyProject/ -flavor Release -args MyParameter ``` diff --git a/docs/cli/target.md b/docs/cli/target.md index 56166159..2225ffea 100644 --- a/docs/cli/target.md +++ b/docs/cli/target.md @@ -17,5 +17,5 @@ soup target Print the target directory for a release Recipe in a different directory with the release flavor. ``` -soup target ./Code/MyProject/ -flavor release +soup target ./Code/MyProject/ -flavor Release ``` diff --git a/scripts/linux/build b/scripts/linux/build index eb14befb..31dfcb38 100755 --- a/scripts/linux/build +++ b/scripts/linux/build @@ -19,6 +19,10 @@ eval $SCRIPTS_DIR/build-swhere $FLAVOR echo $SCRIPTS_DIR/build-packagemanager $FLAVOR eval $SCRIPTS_DIR/build-packagemanager $FLAVOR +# Build Tools +echo $SCRIPTS_DIR/build-tools $FLAVOR +eval $SCRIPTS_DIR/build-tools $FLAVOR + # Build View echo $SCRIPTS_DIR/build-view $FLAVOR eval $SCRIPTS_DIR/build-view $FLAVOR \ No newline at end of file diff --git a/scripts/linux/build-client b/scripts/linux/build-client index a43dd4b0..8237362a 100755 --- a/scripts/linux/build-client +++ b/scripts/linux/build-client @@ -12,6 +12,10 @@ CODE_DIR=$ROOT_DIR/code OUTPUT_DIR=$ROOT_DIR/out CLIENT_CLI_DIR=$CODE_DIR/client/cli +# Restore the client +echo soup restore $CLIENT_CLI_DIR +eval soup restore $CLIENT_CLI_DIR + # Build the client echo soup build $CLIENT_CLI_DIR -flavor $FLAVOR eval soup build $CLIENT_CLI_DIR -flavor $FLAVOR \ No newline at end of file diff --git a/scripts/linux/build-tools b/scripts/linux/build-tools index d254dde5..aeab0fb2 100755 --- a/scripts/linux/build-tools +++ b/scripts/linux/build-tools @@ -1,13 +1,18 @@ #!/bin/bash -echo "Build SoupView!" +echo "Build SoupTools!" # Stop on first error set -e +FLAVOR="$1" SCRIPTS_DIR=$(dirname "$0") CODE_DIR=$SCRIPTS_DIR/../../code TOOLS_DIR=$CODE_DIR/client/tools +# Restore tools +echo soup restore $TOOLS_DIR +eval soup restore $TOOLS_DIR + # Build tools -echo soup build $TOOLS_DIR -flavor Release -eval soup build $TOOLS_DIR -flavor Release +echo soup build $TOOLS_DIR -flavor $FLAVOR +eval soup build $TOOLS_DIR -flavor $FLAVOR diff --git a/scripts/linux/build-view b/scripts/linux/build-view index feb9de4f..a5b47fe5 100755 --- a/scripts/linux/build-view +++ b/scripts/linux/build-view @@ -6,9 +6,13 @@ set -e FLAVOR="$1" SCRIPTS_DIR=$(dirname "$0") -CODE_DIR=$SCRIPTS_DIR/../../code +ROOT_DIR=$SCRIPTS_DIR/../.. +CODE_DIR=$ROOT_DIR/code SWHERE_DIR=$CODE_DIR/generate-sharp/soup-view +# Cleanup old publish to work around bug in publish +rm -r -f $ROOT_DIR/out/msbuild/bin/SoupView/$FLAVOR/net9.0/linux-x64/publish/ + # Build SWhere tool echo dotnet publish $SWHERE_DIR -c $FLAVOR -r linux-x64 --self-contained eval dotnet publish $SWHERE_DIR -c $FLAVOR -r linux-x64 --self-contained diff --git a/scripts/windows/build-client.cmd b/scripts/windows/build-client.cmd index 93495a2a..973ccea1 100644 --- a/scripts/windows/build-client.cmd +++ b/scripts/windows/build-client.cmd @@ -8,6 +8,11 @@ SET OutputDir=%RootDir%\out SET ClientCLIDir=%CodeDir%\client\cli SET MonitorClientDir=%CodeDir%\monitor\client +REM - Restore the client +echo soup restore %ClientCLIDir% +call soup restore %ClientCLIDir% +if %ERRORLEVEL% NEQ 0 exit /B %ERRORLEVEL% + REM - Build each version of the monitor client dll echo soup build %MonitorClientDir% -architecture x64 -flavor %Flavor% call soup build %MonitorClientDir% -architecture x64 -flavor %Flavor% diff --git a/scripts/windows/build-tools.cmd b/scripts/windows/build-tools.cmd index 60a5b93f..d5be1da9 100644 --- a/scripts/windows/build-tools.cmd +++ b/scripts/windows/build-tools.cmd @@ -6,6 +6,11 @@ SET RootDir=%ScriptsDir%..\.. SET CodeDir=%RootDir%\code SET ToolsDir=%CodeDir%\client\tools +REM - Restore Tools +echo soup restore %ToolsDir% +call soup restore %ToolsDir% +if %ERRORLEVEL% NEQ 0 exit /B %ERRORLEVEL% + REM - Build Tools echo soup build %ToolsDir% -flavor %Flavor% call soup build %ToolsDir% -flavor %Flavor%