Skip to content

Commit af8a00d

Browse files
authored
Merge branch 'main' into conan-test-windows
2 parents f0ccf7b + d8853f8 commit af8a00d

File tree

4 files changed

+186
-22
lines changed

4 files changed

+186
-22
lines changed

.github/workflows/conan.yml

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ jobs:
4040
github.event_name == 'schedule' &&
4141
steps.git_info.outputs.current_commit == steps.last_successful_commit.outputs.commit-hash
4242
43-
# TODO (RSDK-10666) add windows build testing
44-
4543
build_macos:
4644
if: github.repository_owner == 'viamrobotics'
4745
needs: [prepare]
@@ -215,3 +213,34 @@ jobs:
215213
--tool-requires=b2/5.3.1 --build=b2/5.3.1 -s compiler.cppstd=14 -s:a compiler.cppstd=14
216214
217215
conan create . --build=missing -s compiler.cppstd=14 -s:a compiler.cppstd=14
216+
217+
build_windows:
218+
if: github.repository_owner == 'viamrobotics'
219+
needs: [prepare]
220+
runs-on: windows-latest
221+
strategy:
222+
fail-fast: false
223+
matrix:
224+
include:
225+
- target: x86_64-windows
226+
platform: windows_x86_64
227+
steps:
228+
- name: Checkout Code
229+
uses: actions/checkout@v4
230+
with:
231+
ref: ${{ needs.prepare.outputs.sha }}
232+
233+
- name: Install dependencies
234+
run: choco install -y conan git
235+
236+
- name: Create package
237+
shell: powershell
238+
run: |
239+
Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1
240+
refreshenv
241+
conan profile detect
242+
conan create . --build=missing -o "&:shared=False"
243+
env:
244+
CONAN_USER_HOME: c:/cache
245+
CONAN_USER_HOME_SHORT: c:/cache/conan_shortpaths
246+

test_package/CMakeLists.txt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
cmake_minimum_required(VERSION 3.25 FATAL_ERROR)
2+
3+
4+
project(viam-cpp-sdk-example-project
5+
DESCRIPTION "Viam Robotics C++ SDK - CMake Example Project"
6+
HOMEPAGE_URL https://github.com/viamrobotics/viam-cpp-sdk
7+
LANGUAGES CXX
8+
)
9+
10+
11+
# Use of the C++ SDK requires C++14.
12+
set(CMAKE_CXX_STANDARD 14)
13+
set(CMAKE_CXX_STANDARD_REQUIRED True)
14+
set(CMAKE_CXX_EXTENSIONS OFF)
15+
16+
17+
# Everything needs threads, and prefer -pthread if available
18+
set(THREADS_PREFER_PTHREAD_FLAG ON)
19+
find_package(Threads REQUIRED)
20+
21+
22+
# In practice, you should set a minimum required version
23+
# when loading the SDK:
24+
#
25+
# find_package(viam-cpp-sdk 1.0.2 CONFIG REQUIRED COMPONENTS viamsdk)
26+
#
27+
find_package(viam-cpp-sdk CONFIG REQUIRED viamsdk)
28+
29+
add_executable(example_module main.cpp)
30+
31+
target_link_libraries(example_module
32+
viam-cpp-sdk::viamsdk
33+
)

test_package/conanfile.py

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import subprocess
21
import os
2+
from io import StringIO
33

44
from conan import ConanFile
55
from conan.errors import ConanException
66
from conan.tools.cmake import CMake, cmake_layout
77
from conan.tools.build import can_run
8-
from conan.tools.env import VirtualRunEnv
8+
9+
def run_helper(conanfile, args, env, out):
10+
conanfile.run(args, env=env, stdout=out)
911

1012
class viamCppSdkTest(ConanFile):
1113
settings = "os", "compiler", "build_type", "arch"
@@ -20,29 +22,16 @@ def build(self):
2022
cmake.build()
2123

2224
def layout(self):
23-
cmake_layout(self, src_folder="../src/viam/examples/project/cmake")
25+
cmake_layout(self)
2426

2527
def test(self):
2628
if can_run(self):
29+
output = StringIO()
2730
sock = "fake-socket-path"
2831

29-
cmd = os.path.join(self.cpp.build.bindir, "example_module")
30-
31-
# the ConanFile run method is a wrapper around Popen, but it only returns the retcode.
32-
# A properly intialized module waits indefinitely on a signal, so we have to use Popen manually.
33-
# Use VirtualRunEnv to perform the equivalent of passing env="conanrun" to self.run, so that
34-
# shared builds have a properly set LD_LIBRARY_PATH among other things.
35-
env = VirtualRunEnv(self).vars()
36-
proc = subprocess.Popen([cmd, sock], stdout=subprocess.PIPE, text=True, env=env)
37-
38-
out = None
32+
self.run(os.path.join(self.cpp.build.bindir, f"example_module {sock}"), stdout=output, env="conanrun")
3933

40-
try:
41-
out = proc.communicate(timeout=2)[0]
42-
except subprocess.TimeoutExpired:
43-
proc.terminate()
44-
out = proc.communicate()[0]
45-
pass
34+
print(output.getvalue())
4635

47-
if f"Module listening on {sock}" not in out:
36+
if f"Module listening on {sock}" not in output.getvalue():
4837
raise ConanException(f"Simple example failed to start module listening")

test_package/main.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// This file is adapted from examples/modules/simple/main.cpp, but it runs the module
2+
// service in a thread which is killed after two seconds. This is a workaround to conform with the
3+
// expected format of a conan test package executable.
4+
#include <iostream>
5+
#include <memory>
6+
#include <sstream>
7+
#include <thread>
8+
9+
#include <viam/sdk/common/exception.hpp>
10+
#include <viam/sdk/common/instance.hpp>
11+
#include <viam/sdk/common/proto_value.hpp>
12+
#include <viam/sdk/components/sensor.hpp>
13+
#include <viam/sdk/config/resource.hpp>
14+
#include <viam/sdk/log/logging.hpp>
15+
#include <viam/sdk/module/service.hpp>
16+
#include <viam/sdk/registry/registry.hpp>
17+
#include <viam/sdk/resource/reconfigurable.hpp>
18+
19+
using namespace viam::sdk;
20+
21+
// Implements a trivial sensor component, constructed with a ResourceConfig that specifies a
22+
// "multiplier" value which is then returned as the only sensor reading.
23+
class MySensor : public Sensor, public Reconfigurable {
24+
public:
25+
MySensor(const ResourceConfig& cfg) : Sensor(cfg.name()) {
26+
this->reconfigure({}, cfg);
27+
}
28+
29+
static std::vector<std::string> validate(const ResourceConfig&);
30+
31+
void reconfigure(const Dependencies&, const ResourceConfig&) override;
32+
33+
ProtoStruct do_command(const ProtoStruct&) override;
34+
35+
std::vector<GeometryConfig> get_geometries(const ProtoStruct&) override {
36+
throw Exception("method not supported");
37+
}
38+
39+
ProtoStruct get_readings(const ProtoStruct&) override;
40+
41+
private:
42+
double multiplier_{1.0};
43+
};
44+
45+
std::vector<std::string> MySensor::validate(const ResourceConfig& cfg) {
46+
auto itr = cfg.attributes().find("multiplier");
47+
if (itr != cfg.attributes().end()) {
48+
const double* multiplier = itr->second.get<double>();
49+
if (!multiplier) {
50+
throw Exception("multiplier must be a number value");
51+
}
52+
53+
if (*multiplier == 0.0) {
54+
throw Exception("multiplier cannot be zero");
55+
}
56+
}
57+
58+
return {};
59+
}
60+
61+
void MySensor::reconfigure(const Dependencies&, const ResourceConfig& cfg) {
62+
auto itr = cfg.attributes().find("multiplier");
63+
if (itr != cfg.attributes().end()) {
64+
const double* multiplier = itr->second.get<double>();
65+
if (multiplier) {
66+
multiplier_ = *multiplier;
67+
}
68+
}
69+
}
70+
71+
ProtoStruct MySensor::do_command(const ProtoStruct& command) {
72+
for (const auto& entry : command) {
73+
// The VIAM_RESOURCE_LOG macro will associate log messages to the current resource and can
74+
// be filtered upon
75+
VIAM_RESOURCE_LOG(info) << "Command entry " << entry.first;
76+
}
77+
78+
return command;
79+
}
80+
81+
ProtoStruct MySensor::get_readings(const ProtoStruct&) {
82+
return {{"signal", multiplier_}};
83+
}
84+
85+
int main(int argc, char** argv) try {
86+
// Every Viam C++ SDK program must have one and only one Instance object which is created before
87+
// any other C++ SDK objects and stays alive until all Viam C++ SDK objects are destroyed.
88+
Instance inst;
89+
90+
// Write general log statements with the VIAM_SDK_LOG macro
91+
VIAM_SDK_LOG(info) << "Starting up simple sensor module";
92+
93+
Model mysensor_model("viam", "sensor", "mysensor");
94+
95+
std::shared_ptr<ModelRegistration> mr = std::make_shared<ModelRegistration>(
96+
API::get<Sensor>(),
97+
mysensor_model,
98+
[](Dependencies, ResourceConfig cfg) { return std::make_unique<MySensor>(cfg); },
99+
&MySensor::validate);
100+
101+
std::vector<std::shared_ptr<ModelRegistration>> mrs = {mr};
102+
auto my_mod = std::make_shared<ModuleService>(argc, argv, mrs);
103+
104+
std::thread t{[&my_mod] { my_mod->serve(); }};
105+
std::this_thread::sleep_for(std::chrono::seconds{2});
106+
107+
t.detach();
108+
109+
return EXIT_SUCCESS;
110+
} catch (const viam::sdk::Exception& ex) {
111+
std::cerr << "main failed with exception: " << ex.what() << "\n";
112+
return EXIT_FAILURE;
113+
}

0 commit comments

Comments
 (0)