-
Notifications
You must be signed in to change notification settings - Fork 23
RSDK-10366 - rust utils for windows #416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RSDK-10366 - rust utils for windows #416
Conversation
CMakeLists.txt
Outdated
elseif(NOT WIN32 OR (CMAKE_SYSTEM_PROCESSOR STREQUAL "X86") OR (CMAKE_SYSTEM_PROCESSOR STREQUAL "X64")) # TODO(RSDK-10366): Currently, rust_utils is not published for windows aarch, so don't even try downloading | ||
set(lvru_system_name ${CMAKE_SYSTEM_NAME}) | ||
if (CMAKE_SYSTEM_NAME STREQUAL "Cygwin") | ||
set(lvru_system_name "windows") | ||
endif() | ||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") | ||
set(lvru_system_name "macosx") | ||
endif() | ||
set(lvru_system_processor ${CMAKE_SYSTEM_PROCESSOR}) | ||
if ((CMAKE_SYSTEM_PROCESSOR STREQUAL "X86") OR (CMAKE_SYSTEM_PROCESSOR STREQUAL "X64")) | ||
set(lvru_system_processor "x86_64") | ||
endif() | ||
file( | ||
DOWNLOAD | ||
https://github.com/viamrobotics/rust-utils/releases/latest/download/${CMAKE_SHARED_LIBRARY_PREFIX}viam_rust_utils-${lvru_system_name}_${CMAKE_SYSTEM_PROCESSOR}${CMAKE_STATIC_LIBRARY_SUFFIX} | ||
https://github.com/viamrobotics/rust-utils/releases/latest/download/${CMAKE_SHARED_LIBRARY_PREFIX}viam_rust_utils-${lvru_system_name}_${lvru_system_processor}${CMAKE_STATIC_LIBRARY_SUFFIX} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should hopefully download rust-utils on windows systems when building the SDK. However, it is currently untested. When I next have access to a windows laptop I will test and confirm. If it doesn't work and is not trivial to get working, I will remove all of this and update the README with instructions on building from source.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is reasonably easy to spin up a windows machine in GCP and RDP into it if you just need a quick test.
src/viam/sdk/rpc/dial.cpp
Outdated
std::string address; | ||
if (tcp_check.first != localhost_prefix.end()) { | ||
// proxy path is not a localhost address and is therefore a UDS socket | ||
address += "unix://"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 62d40eb#diff-03661151ee3ff17fde17964451d2ea2fbd2322f2bd21f4851eade22a2aaad233R254, I found that using unix:
enabled Windows support, while I couldn't get anything with unix://
to work on windows. Per the gRPC docs, the only difference between the two is that the latter form with unix://
is restricted to absolute paths, while unix:
will accept either: https://grpc.github.io/grpc/cpp/md_doc_naming.html.
It might be worth considering just making the switch to unix:
here now, in case client usage on Windows is ever required, this hard to find fact will not need to be rediscovered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah good call, I'm happy to change this to unix:
.
fwiw this PR is actually enabling windows client usage! The restriction was UDS support in tokio, but now that rust-utils
will be using TCP sockets instead on windows, this PR enables us to use rust-utils on windows. but this change definitely still seems good, especially if tokio ever starts supporting UDS on windows.
src/viam/sdk/rpc/dial.cpp
Outdated
uri, entity, type, payload, opts.allows_insecure_downgrade(), float_timeout.count(), ptr); | ||
if (socket_path == NULL) { | ||
if (proxy_path == NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nullptr
is preferred, or just invert the check: if (!proxy_path) {
src/viam/sdk/rpc/dial.cpp
Outdated
free_rust_runtime(ptr); | ||
throw Exception(ErrorCondition::k_connection, "Unable to establish connecting path"); | ||
} | ||
|
||
std::string address("unix://"); | ||
address += socket_path; | ||
std::string localhost_prefix("127.0.0.1"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are other forms of localhost, like ::1
. Probably not important?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the address we get back from rust-utils
is consistently of the form 127.0.0.1:{port}
so I opted for that.
src/viam/sdk/rpc/dial.cpp
Outdated
auto tcp_check = std::mismatch(localhost_prefix.begin(), localhost_prefix.end(), proxy_path); | ||
std::string address; | ||
if (tcp_check.first != localhost_prefix.end()) { | ||
// proxy path is not a localhost address and is therefore a UDS socket |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
S socket
is redundant. Maybe better to say it fully as unix domain socket (UDS)
.
src/viam/sdk/rpc/dial.cpp
Outdated
std::string address("unix://"); | ||
address += socket_path; | ||
std::string localhost_prefix("127.0.0.1"); | ||
auto tcp_check = std::mismatch(localhost_prefix.begin(), localhost_prefix.end(), proxy_path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why std::mismatch
over just std::string::find?
and comparing to npos
? Is this doing something more than just checking for "127.0.0.1" as a substring?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no good reason why! I asked the internet how to find a substring in C++ and somehow the first thing I landed on was an SO post recommending std::mismatch
😅 I'll switch to std::string::find
.
CMakeLists.txt
Outdated
set(lvru_system_name ${CMAKE_SYSTEM_NAME}) | ||
if (CMAKE_SYSTEM_NAME STREQUAL "Cygwin") | ||
set(lvru_system_name "windows") | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe elseif here?
CMakeLists.txt
Outdated
elseif(NOT WIN32 OR (CMAKE_SYSTEM_PROCESSOR STREQUAL "X86") OR (CMAKE_SYSTEM_PROCESSOR STREQUAL "X64")) # TODO(RSDK-10366): Currently, rust_utils is not published for windows aarch, so don't even try downloading | ||
set(lvru_system_name ${CMAKE_SYSTEM_NAME}) | ||
if (CMAKE_SYSTEM_NAME STREQUAL "Cygwin") | ||
set(lvru_system_name "windows") | ||
endif() | ||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") | ||
set(lvru_system_name "macosx") | ||
endif() | ||
set(lvru_system_processor ${CMAKE_SYSTEM_PROCESSOR}) | ||
if ((CMAKE_SYSTEM_PROCESSOR STREQUAL "X86") OR (CMAKE_SYSTEM_PROCESSOR STREQUAL "X64")) | ||
set(lvru_system_processor "x86_64") | ||
endif() | ||
file( | ||
DOWNLOAD | ||
https://github.com/viamrobotics/rust-utils/releases/latest/download/${CMAKE_SHARED_LIBRARY_PREFIX}viam_rust_utils-${lvru_system_name}_${CMAKE_SYSTEM_PROCESSOR}${CMAKE_STATIC_LIBRARY_SUFFIX} | ||
https://github.com/viamrobotics/rust-utils/releases/latest/download/${CMAKE_SHARED_LIBRARY_PREFIX}viam_rust_utils-${lvru_system_name}_${lvru_system_processor}${CMAKE_STATIC_LIBRARY_SUFFIX} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is reasonably easy to spin up a windows machine in GCP and RDP into it if you just need a quick test.
src/viam/sdk/rpc/dial.cpp
Outdated
@@ -1,3 +1,4 @@ | |||
#include <algorithm> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be down with the other C++ standard library includes around line 4-5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
.github/workflows/conan.yml
Outdated
conan create . ` | ||
--build=missing ` | ||
-o "&:shared=False" | ||
cmake . --preset conan-default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rehashing an offline discussion, this type of invocation is suitable for release.yml
but with conan.yml
we do want to test that we can get a successful conan create
, because that packages and tests the SDK conan package
.github/workflows/conan.yml
Outdated
# TODO (RSDK-10666) Uncomment and fix | ||
#build_windows: | ||
#if: github.repository_owner == 'viamrobotics' | ||
#needs: [prepare] | ||
#runs-on: windows-latest | ||
#strategy: | ||
#fail-fast: false | ||
#matrix: | ||
#include: | ||
#- target: x86_64-windows | ||
#platform: windows_x86_64 | ||
#steps: | ||
#- name: Checkout Code | ||
#uses: actions/checkout@v4 | ||
|
||
#- name: Install dependencies | ||
#uses: crazy-max/ghaction-chocolatey@v3 | ||
#with: | ||
#args: install -y conan git | ||
|
||
#- name: Create package | ||
#shell: powershell | ||
#run: | | ||
#Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1 | ||
#refreshenv | ||
#conan profile detect | ||
#conan create . ` | ||
#--build=missing ` | ||
#-o "&:shared=False" | ||
#env: | ||
#CONAN_USER_HOME: c:/cache | ||
#CONAN_USER_HOME_SHORT: c:/cache/conan_shortpaths |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure when we'll get around to fixing this so I don't know that I feel quite as strongly about leaving this in for future reference. Happy to just remove if preferred.
We can definitely try and fix now, but unless someone has a very clear picture of what's wrong I think I'd prefer to do that in a separate PR so we can lock in the wins here now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think maybe just leave in the TODO/ticket number but the commented code can be removed, we can always consult this diff to see what you had written I believe
.github/workflows/conan.yml
Outdated
# TODO (RSDK-10666) Uncomment and fix | ||
#build_windows: | ||
#if: github.repository_owner == 'viamrobotics' | ||
#needs: [prepare] | ||
#runs-on: windows-latest | ||
#strategy: | ||
#fail-fast: false | ||
#matrix: | ||
#include: | ||
#- target: x86_64-windows | ||
#platform: windows_x86_64 | ||
#steps: | ||
#- name: Checkout Code | ||
#uses: actions/checkout@v4 | ||
|
||
#- name: Install dependencies | ||
#uses: crazy-max/ghaction-chocolatey@v3 | ||
#with: | ||
#args: install -y conan git | ||
|
||
#- name: Create package | ||
#shell: powershell | ||
#run: | | ||
#Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1 | ||
#refreshenv | ||
#conan profile detect | ||
#conan create . ` | ||
#--build=missing ` | ||
#-o "&:shared=False" | ||
#env: | ||
#CONAN_USER_HOME: c:/cache | ||
#CONAN_USER_HOME_SHORT: c:/cache/conan_shortpaths |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think maybe just leave in the TODO/ticket number but the commented code can be removed, we can always consult this diff to see what you had written I believe
oh also were you able to run the release pipeline using this updated yaml? |
More or less! I didn't try running the release pipeline because it involves updating version number and I didn't want to do that and change the rules for when/how the release workflow runs and so on, but the release pipeline as it's written now was run under the Conan script to make sure it ran successfully, and I confirmed that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is working I think you should merge it more or less as is, though I have a few comments and questions here and there that I'd appreciate your taking a look at. I don't think any of them amount to something requiring another round of review.
.github/workflows/conan.yml
Outdated
conan create . ` | ||
--build=missing ` | ||
-o "&:shared=False" ` | ||
-s:h compiler.cppstd=17 ` | ||
-s:h compiler.runtime=static |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I expect you need to keep:
--build=missing `
-o "&:shared=False" `
.github/workflows/release.yml
Outdated
- name: Install dependencies | ||
uses: crazy-max/ghaction-chocolatey@v3 | ||
with: | ||
args: install -y conan git |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still surprised you need this. Chocolatey is pre-installed on windows builders, from what I know. The tflite cpu build uses choco to install conan without doing anything special to install choco itself:
https://github.com/viam-modules/mlmodel-tflite/blob/main/bin/setup.ps1#L5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you're probably right that it's not necessary! I kept it in just because we needed to do a choco
install some way or another, it seemed totally innocuous to include, and I didn't want to do another round of testing to confirm. If you think there's a good reason to switch to a choco install
invocation instead, let me know!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without knowing exactly what it does, it likely is innocuous until "crazy max"'s repo ends up being a vector for / victim of a supply chain attack.
At least when run on windows, all it actually seems to do is call choco
with args
:
https://github.com/crazy-max/ghaction-chocolatey/blob/master/src/main.ts#L22
So, from a risk / reward ratio it looks to me like it shouldn't stay. However, I'm fine with leaving it in for now since I know there has been a lot of back and forth on this and testing is slow. If you end up leaving it in, could you please file a ticket to remove it and add a TODO here before merging?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh that's a good point! this is reason enough to just make the change now imo, tested and it works.
cmake . --preset conan-default | ||
cmake --build --preset=conan-release --target ALL_BUILD install -j 8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious: but why direct invocation of cmake
here rather than conan build
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reasons that weren't entirely clear, the conan build
invocation resulted in a number of undefined symbols coming from the libraries that we were importing in the CMakeLists.txt
. @lia-viam and I spent a short time trying to debug and then just determined that the cmake
invocation was good enough to get releases built. Will fix in RSDK-10666.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to remember if we were in fact using conan build
or that was with conan create
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recall having issues with both, but there was so much back and forth and problem solving that it's hard for me to speak to with total confidence. at any rate I think this seems like a reasonable thing to revisit in the above-linked ticket.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe throw a # TODO(RSDK-10666): ...
on there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
install( | ||
IMPORTED_RUNTIME_ARTIFACTS viam_rust_utils | ||
LIBRARY COMPONENT viam-cpp-sdk_runtime | ||
FILES ${viam_rust_utils_file} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT viam-cpp-sdk_runtime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I may try it out myself after this merges to understand better, because it doesn't align with my understanding of how this ought to be working.
@@ -377,7 +381,7 @@ int main(int argc, char* argv[]) try { | |||
}); | |||
|
|||
// Print out the top 5 (or fewer) label/score pairs. | |||
for (size_t i = 0; i != std::min(5UL, scored_labels.size()); ++i) { | |||
for (size_t i = 0; i != std::min<std::size_t>(5UL, scored_labels.size()); ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or just make the 5 a size_t? I'd expect std::min(size_t{5}, scored_labels.size())
to do the right thing.
src/viam/sdk/CMakeLists.txt
Outdated
# rust-utils doesn't build in CI on windows other than x86_64, so confirm that we're either not | ||
# windows, or if we are windows that we're AMD64, or else that the user has provided their own | ||
# build of rust_utils. | ||
if (NOT WIN32 OR num_viam_rust_utils_files GREATER 0 OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this test just look only at num_viam_rust_utils_files
now? I'd assume that if it is greater than zero then one was found and it should be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may be wrong, but is this a correct assumption? I thought num_viam_rust_utils_files
was evaluated before we downloaded, in order to determine if we should download a rust_utils
file. So the not WIN32 or AMD64
cases are important for the cases where the user hasn't provided a rust-utils
file but we can download one for them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, you are right, I got myself tangled up. I was reacting to having complex logic to decide whether to use rust utils or build the stub here. It just feels like it would be better if all of that tortured logic was isolated up in the top level CMakeLists.txt and this file had a way of making a simple yes/no decision about whether to use the library or build the stubs.
Actually, I wonder if if (TARGET...
is what I'm after: https://cmake.org/cmake/help/latest/command/if.html#target
Again, I know you are eager to land this, but could you please add a TODO (doesn't need a ticket, leave it for someone to clean up later).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
went ahead and switched to if (TARGET viam_rust_utils)
, confirmed that it builds correctly both with a user-provided rust-utils
file and without one.
…stuqdog/cpp-sdk into RSDK-10366-rust-utils-for-windows
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with a few requests for additional comments / TODO's tickets before merge, but no need to post an update with those.
.github/workflows/release.yml
Outdated
- name: Install dependencies | ||
uses: crazy-max/ghaction-chocolatey@v3 | ||
with: | ||
args: install -y conan git |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without knowing exactly what it does, it likely is innocuous until "crazy max"'s repo ends up being a vector for / victim of a supply chain attack.
At least when run on windows, all it actually seems to do is call choco
with args
:
https://github.com/crazy-max/ghaction-chocolatey/blob/master/src/main.ts#L22
So, from a risk / reward ratio it looks to me like it shouldn't stay. However, I'm fine with leaving it in for now since I know there has been a lot of back and forth on this and testing is slow. If you end up leaving it in, could you please file a ticket to remove it and add a TODO here before merging?
cmake . --preset conan-default | ||
cmake --build --preset=conan-release --target ALL_BUILD install -j 8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe throw a # TODO(RSDK-10666): ...
on there.
src/viam/sdk/CMakeLists.txt
Outdated
# rust-utils doesn't build in CI on windows other than x86_64, so confirm that we're either not | ||
# windows, or if we are windows that we're AMD64, or else that the user has provided their own | ||
# build of rust_utils. | ||
if (NOT WIN32 OR num_viam_rust_utils_files GREATER 0 OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, you are right, I got myself tangled up. I was reacting to having complex logic to decide whether to use rust utils or build the stub here. It just feels like it would be better if all of that tortured logic was isolated up in the top level CMakeLists.txt and this file had a way of making a simple yes/no decision about whether to use the library or build the stubs.
Actually, I wonder if if (TARGET...
is what I'm after: https://cmake.org/cmake/help/latest/command/if.html#target
Again, I know you are eager to land this, but could you please add a TODO (doesn't need a ticket, leave it for someone to clean up later).
Adds support for tcp-based rust-utils, updates rust-utils downloading for x86_64 windows.
Tested tcp connection on mac successfully.
Tested on windows: with a properly built
viam_rust_utils.lib
at the root of the directory, I am able to connect as a client via webRTC.Without aedit: with the recent update toviam_rust_utils.lib
at the root of the directory, I instead link in the stubs that were previously being linked, andabort()
out whenever making arust-utils
call (as we were doing previously).rust-utils
, we now successfully downloadrust-utils
if it's not in the root, so long as we're on x86_64.