mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-06-10 09:24:51 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fea238722d | |||
| 178d958c08 | |||
| f9633f366b | |||
| 7a81f3e767 | |||
| bbbbbf7927 | |||
| 5735f84008 | |||
| fe0cf42e5d | |||
| 04100584ce | |||
| 9d3a422916 |
@@ -501,6 +501,7 @@ jobs:
|
||||
run: |
|
||||
cat > version.json << EOF
|
||||
{
|
||||
"latest_version": "${{ steps.version.outputs.VERSION_NUM }}",
|
||||
"version": "${{ steps.version.outputs.VERSION_NUM }}",
|
||||
"releaseDate": "${{ steps.version.outputs.BUILD_DATE_ISO }}",
|
||||
"patch": ${{ steps.version.outputs.PATCH_NUMBER }},
|
||||
|
||||
@@ -140,6 +140,7 @@ jobs:
|
||||
# Generate version.json using cat and heredoc
|
||||
cat > version.json << EOF
|
||||
{
|
||||
"latest_version": "${{ steps.version.outputs.VERSION_FULL }}",
|
||||
"version": "${{ steps.version.outputs.VERSION_FULL }}",
|
||||
"releaseDate": "${{ steps.version.outputs.BUILD_DATE_ISO }}",
|
||||
"patch": ${{ steps.version.outputs.PATCH_NUMBER }},
|
||||
|
||||
@@ -1,11 +1,36 @@
|
||||
#include "mouse_controller.h"
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "rd_log.h"
|
||||
|
||||
namespace crossdesk {
|
||||
namespace {
|
||||
|
||||
constexpr auto kDoubleClickInterval = std::chrono::milliseconds(500);
|
||||
constexpr int kDoubleClickMaxDistance = 8;
|
||||
constexpr int kMaxClickState = 3;
|
||||
|
||||
bool IsWithinClickDistance(int x1, int y1, int x2, int y2) {
|
||||
return std::abs(x1 - x2) <= kDoubleClickMaxDistance &&
|
||||
std::abs(y1 - y2) <= kDoubleClickMaxDistance;
|
||||
}
|
||||
|
||||
void SetClickState(CGEventRef event, int click_state) {
|
||||
if (!event) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGEventSetIntegerValueField(
|
||||
event, kCGMouseEventClickState,
|
||||
std::max(1, std::min(click_state, kMaxClickState)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MouseController::MouseController() {}
|
||||
|
||||
@@ -19,6 +44,36 @@ int MouseController::Init(std::vector<DisplayInfo> display_info_list) {
|
||||
|
||||
int MouseController::Destroy() { return 0; }
|
||||
|
||||
int MouseController::BeginClick(ClickTracker& tracker, int x, int y) {
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
const bool continues_previous_click =
|
||||
tracker.has_last_down &&
|
||||
now - tracker.last_down_time <= kDoubleClickInterval &&
|
||||
IsWithinClickDistance(tracker.last_down_x, tracker.last_down_y, x, y);
|
||||
|
||||
tracker.click_state = continues_previous_click
|
||||
? std::min(tracker.click_state + 1, kMaxClickState)
|
||||
: 1;
|
||||
tracker.active_click_state = tracker.click_state;
|
||||
tracker.has_last_down = true;
|
||||
tracker.last_down_time = now;
|
||||
tracker.last_down_x = x;
|
||||
tracker.last_down_y = y;
|
||||
|
||||
return tracker.active_click_state;
|
||||
}
|
||||
|
||||
int MouseController::EndClick(ClickTracker& tracker, int x, int y) {
|
||||
const int click_state = tracker.active_click_state;
|
||||
if (!IsWithinClickDistance(tracker.last_down_x, tracker.last_down_y, x, y)) {
|
||||
tracker.has_last_down = false;
|
||||
tracker.click_state = 0;
|
||||
tracker.active_click_state = 1;
|
||||
}
|
||||
|
||||
return click_state;
|
||||
}
|
||||
|
||||
int MouseController::SendMouseCommand(RemoteAction remote_action,
|
||||
int display_index) {
|
||||
if (remote_action.type != ControlType::mouse) {
|
||||
@@ -41,58 +96,69 @@ int MouseController::SendMouseCommand(RemoteAction remote_action,
|
||||
|
||||
const float normalized_x = std::clamp(remote_action.m.x, 0.0f, 1.0f);
|
||||
const float normalized_y = std::clamp(remote_action.m.y, 0.0f, 1.0f);
|
||||
int mouse_pos_x =
|
||||
normalized_x * display_info.width + display_info.left;
|
||||
int mouse_pos_y =
|
||||
normalized_y * display_info.height + display_info.top;
|
||||
int mouse_pos_x = normalized_x * display_info.width + display_info.left;
|
||||
int mouse_pos_y = normalized_y * display_info.height + display_info.top;
|
||||
|
||||
CGEventRef mouse_event = nullptr;
|
||||
CGEventType mouse_type;
|
||||
CGMouseButton mouse_button;
|
||||
CGPoint mouse_point = CGPointMake(mouse_pos_x, mouse_pos_y);
|
||||
int click_state = 1;
|
||||
|
||||
switch (remote_action.m.flag) {
|
||||
case MouseFlag::left_down:
|
||||
mouse_type = kCGEventLeftMouseDown;
|
||||
left_dragging_ = true;
|
||||
click_state = BeginClick(left_click_tracker_, mouse_pos_x, mouse_pos_y);
|
||||
mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point,
|
||||
kCGMouseButtonLeft);
|
||||
SetClickState(mouse_event, click_state);
|
||||
break;
|
||||
case MouseFlag::left_up:
|
||||
mouse_type = kCGEventLeftMouseUp;
|
||||
left_dragging_ = false;
|
||||
click_state = EndClick(left_click_tracker_, mouse_pos_x, mouse_pos_y);
|
||||
mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point,
|
||||
kCGMouseButtonLeft);
|
||||
SetClickState(mouse_event, click_state);
|
||||
break;
|
||||
case MouseFlag::right_down:
|
||||
mouse_type = kCGEventRightMouseDown;
|
||||
right_dragging_ = true;
|
||||
click_state = BeginClick(right_click_tracker_, mouse_pos_x, mouse_pos_y);
|
||||
mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point,
|
||||
kCGMouseButtonRight);
|
||||
SetClickState(mouse_event, click_state);
|
||||
break;
|
||||
case MouseFlag::right_up:
|
||||
mouse_type = kCGEventRightMouseUp;
|
||||
right_dragging_ = false;
|
||||
click_state = EndClick(right_click_tracker_, mouse_pos_x, mouse_pos_y);
|
||||
mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point,
|
||||
kCGMouseButtonRight);
|
||||
SetClickState(mouse_event, click_state);
|
||||
break;
|
||||
case MouseFlag::middle_down:
|
||||
mouse_type = kCGEventOtherMouseDown;
|
||||
click_state = BeginClick(middle_click_tracker_, mouse_pos_x, mouse_pos_y);
|
||||
mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point,
|
||||
kCGMouseButtonCenter);
|
||||
SetClickState(mouse_event, click_state);
|
||||
break;
|
||||
case MouseFlag::middle_up:
|
||||
mouse_type = kCGEventOtherMouseUp;
|
||||
click_state = EndClick(middle_click_tracker_, mouse_pos_x, mouse_pos_y);
|
||||
mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point,
|
||||
kCGMouseButtonCenter);
|
||||
SetClickState(mouse_event, click_state);
|
||||
break;
|
||||
case MouseFlag::wheel_vertical:
|
||||
mouse_event = CGEventCreateScrollWheelEvent(
|
||||
NULL, kCGScrollEventUnitLine, 2, remote_action.m.s, 0);
|
||||
mouse_event = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine,
|
||||
2, remote_action.m.s, 0);
|
||||
break;
|
||||
case MouseFlag::wheel_horizontal:
|
||||
mouse_event = CGEventCreateScrollWheelEvent(
|
||||
NULL, kCGScrollEventUnitLine, 2, 0, remote_action.m.s);
|
||||
mouse_event = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine,
|
||||
2, 0, remote_action.m.s);
|
||||
break;
|
||||
default:
|
||||
if (left_dragging_) {
|
||||
@@ -106,8 +172,8 @@ int MouseController::SendMouseCommand(RemoteAction remote_action,
|
||||
mouse_button = kCGMouseButtonLeft;
|
||||
}
|
||||
|
||||
mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, mouse_point,
|
||||
mouse_button);
|
||||
mouse_event =
|
||||
CGEventCreateMouseEvent(NULL, mouse_type, mouse_point, mouse_button);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#ifndef _MOUSE_CONTROLLER_H_
|
||||
#define _MOUSE_CONTROLLER_H_
|
||||
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
|
||||
#include "device_controller.h"
|
||||
@@ -24,9 +25,24 @@ class MouseController : public DeviceController {
|
||||
virtual int SendMouseCommand(RemoteAction remote_action, int display_index);
|
||||
|
||||
private:
|
||||
struct ClickTracker {
|
||||
bool has_last_down = false;
|
||||
std::chrono::steady_clock::time_point last_down_time{};
|
||||
int last_down_x = 0;
|
||||
int last_down_y = 0;
|
||||
int click_state = 0;
|
||||
int active_click_state = 1;
|
||||
};
|
||||
|
||||
int BeginClick(ClickTracker& tracker, int x, int y);
|
||||
int EndClick(ClickTracker& tracker, int x, int y);
|
||||
|
||||
std::vector<DisplayInfo> display_info_list_;
|
||||
bool left_dragging_ = false;
|
||||
bool right_dragging_ = false;
|
||||
ClickTracker left_click_tracker_;
|
||||
ClickTracker right_click_tracker_;
|
||||
ClickTracker middle_click_tracker_;
|
||||
};
|
||||
} // namespace crossdesk
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -158,6 +158,9 @@ struct TranslationRow {
|
||||
X(signal_connected, u8"已连接服务器", "Connected", u8"Подключено к серверу") \
|
||||
X(signal_disconnected, u8"未连接服务器", "Disconnected", \
|
||||
u8"Нет подключения к серверу") \
|
||||
X(signal_tls_cert_error, u8"证书验证失败,请重新安装自托管根证书", \
|
||||
"Certificate verification failed. Reinstall the self-hosted root certificate.", \
|
||||
u8"Ошибка проверки сертификата. Переустановите корневой сертификат.") \
|
||||
X(p2p_connected, u8"对等连接已建立", "P2P Connected", u8"P2P подключено") \
|
||||
X(p2p_disconnected, u8"对等连接已断开", "P2P Disconnected", \
|
||||
u8"P2P отключено") \
|
||||
|
||||
+35
-20
@@ -1719,26 +1719,6 @@ int Render::DrawServerWindow() {
|
||||
}
|
||||
|
||||
int Render::Run() {
|
||||
latest_version_info_ = CheckUpdate();
|
||||
if (!latest_version_info_.empty() &&
|
||||
latest_version_info_.contains("version") &&
|
||||
latest_version_info_["version"].is_string()) {
|
||||
latest_version_ = 'v' + latest_version_info_["version"].get<std::string>();
|
||||
if (latest_version_info_.contains("releaseNotes") &&
|
||||
latest_version_info_["releaseNotes"].is_string()) {
|
||||
release_notes_ = latest_version_info_["releaseNotes"].get<std::string>();
|
||||
} else {
|
||||
release_notes_ = "";
|
||||
}
|
||||
update_available_ = IsNewerVersion(CROSSDESK_VERSION, latest_version_);
|
||||
if (update_available_) {
|
||||
show_update_notification_window_ = true;
|
||||
}
|
||||
} else {
|
||||
latest_version_ = "";
|
||||
update_available_ = false;
|
||||
}
|
||||
|
||||
path_manager_ = std::make_unique<PathManager>("CrossDesk");
|
||||
if (path_manager_) {
|
||||
exec_log_path_ = path_manager_->GetLogPath().string();
|
||||
@@ -1767,6 +1747,41 @@ int Render::Run() {
|
||||
InitializeLogger();
|
||||
LOG_INFO("CrossDesk version: {}", CROSSDESK_VERSION);
|
||||
|
||||
latest_version_info_ = CheckUpdate();
|
||||
if (!latest_version_info_.empty()) {
|
||||
std::string version;
|
||||
if (latest_version_info_.contains("latest_version") &&
|
||||
latest_version_info_["latest_version"].is_string()) {
|
||||
version = latest_version_info_["latest_version"].get<std::string>();
|
||||
} else if (latest_version_info_.contains("version") &&
|
||||
latest_version_info_["version"].is_string()) {
|
||||
version = latest_version_info_["version"].get<std::string>();
|
||||
}
|
||||
|
||||
if (!version.empty()) {
|
||||
latest_version_ = 'v' + version;
|
||||
} else {
|
||||
latest_version_ = "";
|
||||
}
|
||||
if (latest_version_info_.contains("releaseNotes") &&
|
||||
latest_version_info_["releaseNotes"].is_string()) {
|
||||
release_notes_ = latest_version_info_["releaseNotes"].get<std::string>();
|
||||
} else {
|
||||
release_notes_ = "";
|
||||
}
|
||||
update_available_ =
|
||||
!version.empty() && IsNewerVersion(CROSSDESK_VERSION, latest_version_);
|
||||
LOG_INFO("Update check: current={}, latest={}, available={}",
|
||||
CROSSDESK_VERSION, latest_version_, update_available_);
|
||||
if (update_available_) {
|
||||
show_update_notification_window_ = true;
|
||||
}
|
||||
} else {
|
||||
latest_version_ = "";
|
||||
update_available_ = false;
|
||||
LOG_WARN("Update check skipped: version.json is empty or missing latest_version");
|
||||
}
|
||||
|
||||
InitializeSettings();
|
||||
InitializeSDL();
|
||||
InitializeModules();
|
||||
|
||||
@@ -1231,6 +1231,8 @@ void Render::OnSignalStatusCb(SignalStatus status, const char* user_id,
|
||||
render->signal_connected_ = false;
|
||||
} else if (SignalStatus::SignalServerClosed == status) {
|
||||
render->signal_connected_ = false;
|
||||
} else if (SignalStatus::SignalTlsCertError == status) {
|
||||
render->signal_connected_ = false;
|
||||
}
|
||||
} else {
|
||||
if (client_id.rfind("C-", 0) != 0) {
|
||||
@@ -1258,6 +1260,8 @@ void Render::OnSignalStatusCb(SignalStatus status, const char* user_id,
|
||||
props->signal_connected_ = false;
|
||||
} else if (SignalStatus::SignalServerClosed == status) {
|
||||
props->signal_connected_ = false;
|
||||
} else if (SignalStatus::SignalTlsCertError == status) {
|
||||
props->signal_connected_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,20 +26,31 @@ int Render::StatusBar() {
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
draw_list->AddCircleFilled(dot_pos, status_bar_height * 0.25f,
|
||||
ImColor(1.0f, 1.0f, 1.0f), 100);
|
||||
bool tls_cert_error =
|
||||
signal_status_ == SignalStatus::SignalTlsCertError;
|
||||
draw_list->AddCircleFilled(dot_pos, status_bar_height * 0.2f,
|
||||
ImColor(signal_connected_ ? 0.0f : 1.0f,
|
||||
signal_connected_ ? 1.0f : 0.0f, 0.0f),
|
||||
tls_cert_error
|
||||
? ImColor(1.0f, 0.65f, 0.0f)
|
||||
: ImColor(signal_connected_ ? 0.0f : 1.0f,
|
||||
signal_connected_ ? 1.0f : 0.0f,
|
||||
0.0f),
|
||||
100);
|
||||
|
||||
ImGui::SetWindowFontScale(0.6f);
|
||||
const char* signal_status_text =
|
||||
tls_cert_error
|
||||
? localization::signal_tls_cert_error[localization_language_index_]
|
||||
.c_str()
|
||||
: (signal_connected_
|
||||
? localization::signal_connected[localization_language_index_]
|
||||
.c_str()
|
||||
: localization::signal_disconnected
|
||||
[localization_language_index_]
|
||||
.c_str());
|
||||
draw_list->AddText(
|
||||
ImVec2(status_bar_width * 0.045f,
|
||||
io.DisplaySize.y * (1 - STATUS_BAR_HEIGHT * 0.9f)),
|
||||
ImColor(0.0f, 0.0f, 0.0f),
|
||||
signal_connected_
|
||||
? localization::signal_connected[localization_language_index_].c_str()
|
||||
: localization::signal_disconnected[localization_language_index_]
|
||||
.c_str());
|
||||
ImColor(0.0f, 0.0f, 0.0f), signal_status_text);
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
@@ -8,8 +8,13 @@
|
||||
|
||||
#include <httplib.h>
|
||||
|
||||
#include "rd_log.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cctype>
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
@@ -225,6 +230,85 @@ bool ReadPatchField(const nlohmann::json& json, int* patch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void LogHttpError(const httplib::Result& result) {
|
||||
LOG_WARN("Failed to fetch version.json: error={}, message={}",
|
||||
static_cast<int>(result.error()), httplib::to_string(result.error()));
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
LOG_WARN("version.json SSL error={}, OpenSSL error={}", result.ssl_error(),
|
||||
result.ssl_openssl_error());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CPPHTTPLIB_OPENSSL_SUPPORT) && defined(__linux__)
|
||||
bool PathExists(const std::string& path) {
|
||||
if (path.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
return std::filesystem::exists(path, ec);
|
||||
}
|
||||
|
||||
std::string GetEnvPathIfExists(const char* key) {
|
||||
const char* value = std::getenv(key);
|
||||
if (!value) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const std::string path = value;
|
||||
return PathExists(path) ? path : "";
|
||||
}
|
||||
|
||||
std::string FindFirstExistingPath(
|
||||
const std::vector<std::string>& candidates) {
|
||||
for (const auto& candidate : candidates) {
|
||||
if (PathExists(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void ConfigureLinuxCaCerts(httplib::Client* cli) {
|
||||
const std::string ca_file = [&]() {
|
||||
const std::string env_path = GetEnvPathIfExists("SSL_CERT_FILE");
|
||||
if (!env_path.empty()) {
|
||||
return env_path;
|
||||
}
|
||||
|
||||
return FindFirstExistingPath({
|
||||
"/etc/ssl/certs/ca-certificates.crt",
|
||||
"/etc/pki/tls/certs/ca-bundle.crt",
|
||||
"/etc/ssl/cert.pem",
|
||||
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
|
||||
});
|
||||
}();
|
||||
|
||||
const std::string ca_dir = [&]() {
|
||||
const std::string env_path = GetEnvPathIfExists("SSL_CERT_DIR");
|
||||
if (!env_path.empty()) {
|
||||
return env_path;
|
||||
}
|
||||
|
||||
return FindFirstExistingPath({
|
||||
"/etc/ssl/certs",
|
||||
"/etc/pki/tls/certs",
|
||||
"/etc/openssl/certs",
|
||||
});
|
||||
}();
|
||||
|
||||
if (ca_file.empty() && ca_dir.empty()) {
|
||||
LOG_WARN("No Linux CA bundle found for version.json request; relying on OpenSSL defaults");
|
||||
return;
|
||||
}
|
||||
|
||||
cli->set_ca_cert_path(ca_file, ca_dir);
|
||||
LOG_INFO("Configured version.json TLS CA bundle: file={}, dir={}",
|
||||
ca_file.empty() ? "<none>" : ca_file,
|
||||
ca_dir.empty() ? "<none>" : ca_dir);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string ExtractNumericPart(const std::string& ver) {
|
||||
@@ -312,8 +396,14 @@ nlohmann::json CheckUpdate() {
|
||||
|
||||
cli.set_connection_timeout(5);
|
||||
cli.set_read_timeout(5);
|
||||
cli.set_follow_location(true);
|
||||
|
||||
if (auto res = cli.Get("/version.json")) {
|
||||
#if defined(CPPHTTPLIB_OPENSSL_SUPPORT) && defined(__linux__)
|
||||
ConfigureLinuxCaCerts(&cli);
|
||||
#endif
|
||||
|
||||
auto res = cli.Get("/version.json");
|
||||
if (res) {
|
||||
if (res->status == 200) {
|
||||
try {
|
||||
auto j = nlohmann::json::parse(res->body);
|
||||
@@ -324,16 +414,23 @@ nlohmann::json CheckUpdate() {
|
||||
}
|
||||
latest_patch_ = 0;
|
||||
latest_patch_available_ = ReadPatchField(j, &latest_patch_);
|
||||
LOG_INFO("Fetched version.json: latest_version={}, releaseDate={}, patch={}",
|
||||
j.value("latest_version", j.value("version", "")),
|
||||
j.value("releaseDate", ""),
|
||||
latest_patch_available_ ? latest_patch_ : -1);
|
||||
return j;
|
||||
} catch (std::exception&) {
|
||||
} catch (const std::exception& e) {
|
||||
LOG_WARN("Failed to parse version.json: {}", e.what());
|
||||
ResetLatestMetadata();
|
||||
return nlohmann::json{};
|
||||
}
|
||||
} else {
|
||||
LOG_WARN("Failed to fetch version.json: HTTP status={}", res->status);
|
||||
ResetLatestMetadata();
|
||||
return nlohmann::json{};
|
||||
}
|
||||
} else {
|
||||
LogHttpError(res);
|
||||
ResetLatestMetadata();
|
||||
return nlohmann::json{};
|
||||
}
|
||||
|
||||
+1
-1
Submodule submodules/minirtc updated: bb0fae0617...0d9a9d6a32
@@ -74,9 +74,14 @@ function setup_targets()
|
||||
set_kind("binary")
|
||||
set_default(false)
|
||||
add_packages("cpp-httplib")
|
||||
add_deps("rd_log")
|
||||
add_includedirs("src/version_checker")
|
||||
add_files("tests/version_checker_test.cpp",
|
||||
"src/version_checker/version_checker.cpp")
|
||||
if is_os("macosx") then
|
||||
add_defines("CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN")
|
||||
add_frameworks("Security", "CoreFoundation")
|
||||
end
|
||||
|
||||
target("screen_capturer")
|
||||
set_kind("object")
|
||||
@@ -177,6 +182,10 @@ function setup_targets()
|
||||
add_deps("rd_log")
|
||||
add_files("src/version_checker/*.cpp")
|
||||
add_includedirs("src/version_checker", {public = true})
|
||||
if is_os("macosx") then
|
||||
add_defines("CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN")
|
||||
add_frameworks("Security", "CoreFoundation")
|
||||
end
|
||||
|
||||
target("tools")
|
||||
set_kind("object")
|
||||
|
||||
Reference in New Issue
Block a user