From bac111d68533d13a443e570d64c3205def2b42fc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 23 Nov 2025 15:38:51 +0000 Subject: [PATCH 01/12] Initial plan From ef680dadf19bfe076a1e51e8c7e12e6aec63c1b5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 23 Nov 2025 15:55:11 +0000 Subject: [PATCH 02/12] Integrate libcurl for HTTP requests Co-authored-by: ckrause <840744+ckrause@users.noreply.github.com> --- src/Makefile | 7 +- src/Makefile.linux-arm64.mk | 3 +- src/Makefile.linux-x86.mk | 3 +- src/Makefile.macos-arm64.mk | 1 + src/Makefile.macos-x86.mk | 1 + src/Makefile.windows.mk | 3 +- src/sys/web_client.cpp | 236 +++++++++++++++++++++++------------- 7 files changed, 162 insertions(+), 92 deletions(-) diff --git a/src/Makefile b/src/Makefile index 364a4d25..4be09fe8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,8 @@ CXXFLAGS += -I. -g -Wall -Werror -fmessage-length=0 -std=c++17 +# Default curl libs for dynamic linking (can be overridden by platform-specific makefiles) +CURL_LIBS ?= -lcurl + ifdef LODA_VERSION CXXFLAGS += -DLODA_VERSION=$(LODA_VERSION) endif @@ -21,14 +24,14 @@ OBJS = base/uid.o \ loda: CXXFLAGS += -O2 loda: $(OBJS) - $(CXX) $(LDFLAGS) -o loda $(OBJS) + $(CXX) $(LDFLAGS) -o loda $(OBJS) $(CURL_LIBS) [ -L ../loda ] || ( cd .. && ln -s src/loda loda ) du -sh loda coverage: CXXFLAGS += -O0 -fprofile-arcs -ftest-coverage coverage: LDFLAGS += --coverage coverage: $(OBJS) - $(CXX) $(LDFLAGS) -o loda $(OBJS) + $(CXX) $(LDFLAGS) -o loda $(OBJS) $(CURL_LIBS) [ -L ../loda ] || ( cd .. && ln -s src/loda loda ) cd .. && ./loda test && cd src gcov $(OBJS:.o=.cpp) diff --git a/src/Makefile.linux-arm64.mk b/src/Makefile.linux-arm64.mk index 920d3972..5aae0303 100644 --- a/src/Makefile.linux-arm64.mk +++ b/src/Makefile.linux-arm64.mk @@ -2,7 +2,8 @@ # see https://stackoverflow.com/questions/35116327/when-g-static-link-pthread-cause-segmentation-fault-why CXX = aarch64-linux-gnu-g++ CXXFLAGS += -pthread -flto=auto -LDFLAGS = -static -static-libstdc++ -static-libgcc -lrt -pthread -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -s -flto=auto +LDFLAGS = -static-libstdc++ -static-libgcc -pthread -s -flto=auto +CURL_LIBS = -lcurl # END PLATFORM CONFIG FOR LINUX ARM64 include Makefile diff --git a/src/Makefile.linux-x86.mk b/src/Makefile.linux-x86.mk index e03f414e..0ed81abc 100644 --- a/src/Makefile.linux-x86.mk +++ b/src/Makefile.linux-x86.mk @@ -2,7 +2,8 @@ # see https://stackoverflow.com/questions/35116327/when-g-static-link-pthread-cause-segmentation-fault-why CXX = x86_64-linux-gnu-g++ CXXFLAGS += -pthread -flto=auto -LDFLAGS = -static -static-libstdc++ -static-libgcc -lrt -pthread -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -s -flto=auto +LDFLAGS = -static-libstdc++ -static-libgcc -pthread -s -flto=auto +CURL_LIBS = -lcurl # END PLATFORM CONFIG FOR LINUX X86 include Makefile diff --git a/src/Makefile.macos-arm64.mk b/src/Makefile.macos-arm64.mk index dec52581..e25ac6a4 100644 --- a/src/Makefile.macos-arm64.mk +++ b/src/Makefile.macos-arm64.mk @@ -2,6 +2,7 @@ CXX = clang++ CXXFLAGS = -target arm64-apple-macos14 -flto=thin LDFLAGS = -target arm64-apple-macos14 -flto=thin +CURL_LIBS = -lcurl # END PLATFORM CONFIG FOR MAC OS ARM64 include Makefile diff --git a/src/Makefile.macos-x86.mk b/src/Makefile.macos-x86.mk index d2944780..6a7d6e64 100644 --- a/src/Makefile.macos-x86.mk +++ b/src/Makefile.macos-x86.mk @@ -2,6 +2,7 @@ CXX = clang++ CXXFLAGS = -target x86_64-apple-macos14 -flto=thin LDFLAGS = -target x86_64-apple-macos14 -flto=thin +CURL_LIBS = -lcurl # END PLATFORM CONFIG FOR MAC OS X86 include Makefile diff --git a/src/Makefile.windows.mk b/src/Makefile.windows.mk index 20a6355c..ea10c94c 100644 --- a/src/Makefile.windows.mk +++ b/src/Makefile.windows.mk @@ -1,5 +1,6 @@ CXXFLAGS = /I. /std:c++17 /O2 /GL LDFLAGS = /link /LTCG +CURL_LIBS = libcurl.lib !IFDEF LODA_VERSION CXXFLAGS = $(CXXFLAGS) /DLODA_VERSION=$(LODA_VERSION) @@ -23,7 +24,7 @@ SRCS = base/uid.cpp \ sys/csv.cpp sys/file.cpp sys/git.cpp sys/jute.cpp sys/log.cpp sys/metrics.cpp sys/process.cpp sys/setup.cpp sys/util.cpp sys/web_client.cpp loda: $(SRCS) - cl /EHsc /Feloda.exe $(CXXFLAGS) $(SRCS) $(LDFLAGS) + cl /EHsc /Feloda.exe $(CXXFLAGS) $(SRCS) $(LDFLAGS) $(CURL_LIBS) copy loda.exe .. clean: diff --git a/src/sys/web_client.cpp b/src/sys/web_client.cpp index 6533c368..fdbacf25 100644 --- a/src/sys/web_client.cpp +++ b/src/sys/web_client.cpp @@ -1,67 +1,98 @@ #include "sys/web_client.hpp" +#include +#include + +#include + #include "sys/file.hpp" #include "sys/log.hpp" -enum WebClientType { WC_UNKNOWN = 0, WC_CURL = 1, WC_WGET = 2 }; - -int64_t WebClient::WEB_CLIENT_TYPE = WC_UNKNOWN; +int64_t WebClient::WEB_CLIENT_TYPE = 0; void WebClient::initWebClient() { - if (WEB_CLIENT_TYPE == WC_UNKNOWN) { - const std::string curl_cmd = "curl --version " + getNullRedirect(); - const std::string wget_cmd = "wget --version " + getNullRedirect(); - if (system(curl_cmd.c_str()) == 0) { - WEB_CLIENT_TYPE = WC_CURL; - } else if (system(wget_cmd.c_str()) == 0) { - WEB_CLIENT_TYPE = WC_WGET; - } else { - Log::get().error("No web client found. Please install curl or wget.", - true); - } + if (WEB_CLIENT_TYPE == 0) { + curl_global_init(CURL_GLOBAL_DEFAULT); + WEB_CLIENT_TYPE = 1; } } +namespace { + +// Callback function to write data to a file +size_t writeFileCallback(void* contents, size_t size, size_t nmemb, + void* userp) { + std::ofstream* file = static_cast(userp); + size_t total_size = size * nmemb; + file->write(static_cast(contents), total_size); + return total_size; +} + +// Callback function to write data to a string +size_t writeStringCallback(void* contents, size_t size, size_t nmemb, + void* userp) { + std::string* str = static_cast(userp); + size_t total_size = size * nmemb; + str->append(static_cast(contents), total_size); + return total_size; +} + +// Callback function to read data from a file +size_t readFileCallback(void* ptr, size_t size, size_t nmemb, void* userp) { + std::ifstream* file = static_cast(userp); + size_t total_size = size * nmemb; + file->read(static_cast(ptr), total_size); + return file->gcount(); +} + +} // namespace + bool WebClient::get(const std::string& url, const std::string& local_path, bool silent, bool fail_on_error, bool insecure) { - std::string url_processed; - size_t len = url.length(); - for (size_t pos = 0; pos < len; pos++) { - if (url[pos] == '&' || url[pos] == '|') { -#ifdef _WIN64 - url_processed.push_back('^'); -#else - url_processed.push_back('\\'); -#endif + initWebClient(); + + CURL* curl = curl_easy_init(); + if (!curl) { + if (fail_on_error) { + Log::get().error("Failed to initialize libcurl", true); } - url_processed.push_back(url[pos]); + return false; } - initWebClient(); - std::string cmd; - switch (WEB_CLIENT_TYPE) { - case WC_CURL: - cmd = "curl"; - if (insecure) { - cmd += " --insecure"; - } - cmd += " -fsSLo \"" + local_path + "\" " + url_processed; - break; - case WC_WGET: - cmd = "wget -q --no-use-server-timestamps -O \"" + local_path + "\" " + - url_processed; - break; - default: - Log::get().error("Unsupported web client for GET request", true); - } - if (system(cmd.c_str()) != 0) { + + std::ofstream file(local_path, std::ios::binary); + if (!file.is_open()) { + curl_easy_cleanup(curl); + if (fail_on_error) { + Log::get().error("Failed to open file for writing: " + local_path, true); + } + return false; + } + + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFileCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &file); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); + if (insecure) { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + } + + CURLcode res = curl_easy_perform(curl); + file.close(); + + if (res != CURLE_OK) { std::remove(local_path.c_str()); + curl_easy_cleanup(curl); if (fail_on_error) { - Log::get().info(cmd); - Log::get().error("Error fetching " + url, true); - } else { - return false; + Log::get().error("Error fetching " + url + ": " + + std::string(curl_easy_strerror(res)), + true); } + return false; } + + curl_easy_cleanup(curl); if (!silent) { Log::get().info("Fetched " + url); } @@ -73,53 +104,84 @@ bool WebClient::postFile(const std::string& url, const std::string& file_path, const std::vector& headers, bool enable_debug) { initWebClient(); - std::string cmd; - switch (WEB_CLIENT_TYPE) { - case WC_CURL: { - cmd = "curl -fsSL"; - if (!auth.empty()) { - cmd += " -u " + auth; - } - if (file_path.empty()) { - cmd += " -X POST"; - } else { - cmd += " --data-binary \"@" + file_path + "\""; - } - for (const auto& header : headers) { - cmd += " -H \"" + header + "\""; - } - break; + + CURL* curl = curl_easy_init(); + if (!curl) { + if (enable_debug) { + Log::get().error("Failed to initialize libcurl", false); } - case WC_WGET: { - cmd = "wget -q"; - if (!auth.empty()) { - auto colon = auth.find(':'); - cmd += " --user '" + auth.substr(0, colon) + "' --password '" + - auth.substr(colon + 1) + "'"; - } - if (file_path.empty()) { - cmd += " --post-data \"\""; - } else { - cmd += " --post-file \"" + file_path + "\""; - } - for (const auto& header : headers) { - cmd += " --header \"" + header + "\""; + return false; + } + + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + + if (!auth.empty()) { + curl_easy_setopt(curl, CURLOPT_USERPWD, auth.c_str()); + } + + struct curl_slist* header_list = nullptr; + for (const auto& header : headers) { + header_list = curl_slist_append(header_list, header.c_str()); + } + if (header_list) { + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); + } + + std::ifstream file; + if (!file_path.empty()) { + file.open(file_path, std::ios::binary); + if (!file.is_open()) { + curl_slist_free_all(header_list); + curl_easy_cleanup(curl); + if (enable_debug) { + Log::get().error("Failed to open file: " + file_path, false); } - break; + return false; } - default: - Log::get().error("Unsupported web client for POST request", true); + + file.seekg(0, std::ios::end); + size_t file_size = file.tellg(); + file.seekg(0, std::ios::beg); + + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, readFileCallback); + curl_easy_setopt(curl, CURLOPT_READDATA, &file); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast(file_size)); + } else { + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0L); } - cmd += " " + url; - const std::string msg = "Executing command: " + cmd; + + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); + + std::string response; + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeStringCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); + if (enable_debug) { - Log::get().info(msg); - } else { - Log::get().debug(msg); - cmd += " " + getNullRedirect(); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + Log::get().info("Posting to URL: " + url); + } + + CURLcode res = curl_easy_perform(curl); + + if (file.is_open()) { + file.close(); } - auto exit_code = system(cmd.c_str()); - return (exit_code == 0); + curl_slist_free_all(header_list); + curl_easy_cleanup(curl); + + if (res != CURLE_OK) { + if (enable_debug) { + Log::get().error("Error posting to " + url + ": " + + std::string(curl_easy_strerror(res)), + false); + } + return false; + } + + return true; } jute::jValue WebClient::getJson(const std::string& url) { From 1c29e7cb4eef01759a79457656ca1823c75c2906 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 23 Nov 2025 15:58:49 +0000 Subject: [PATCH 03/12] Address code review feedback for libcurl integration Co-authored-by: ckrause <840744+ckrause@users.noreply.github.com> --- CHANGELOG.md | 1 + src/sys/web_client.cpp | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b64b496..748bf722 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Use `v2/submissions/` API endpoint to fetch programs * Handle program submissions with `delete` mode +* Integrate libcurl for HTTP requests, replacing external curl/wget tools ## v25.11.9 diff --git a/src/sys/web_client.cpp b/src/sys/web_client.cpp index fdbacf25..a8353a02 100644 --- a/src/sys/web_client.cpp +++ b/src/sys/web_client.cpp @@ -14,6 +14,9 @@ void WebClient::initWebClient() { if (WEB_CLIENT_TYPE == 0) { curl_global_init(CURL_GLOBAL_DEFAULT); WEB_CLIENT_TYPE = 1; + // Note: curl_global_cleanup() is intentionally not called as it's not + // thread-safe and the library remains usable for the lifetime of the + // program. This is a common pattern for libcurl usage. } } @@ -140,7 +143,17 @@ bool WebClient::postFile(const std::string& url, const std::string& file_path, } file.seekg(0, std::ios::end); - size_t file_size = file.tellg(); + std::streampos pos = file.tellg(); + if (pos == std::streampos(-1)) { + file.close(); + curl_slist_free_all(header_list); + curl_easy_cleanup(curl); + if (enable_debug) { + Log::get().error("Failed to determine file size: " + file_path, false); + } + return false; + } + size_t file_size = static_cast(pos); file.seekg(0, std::ios::beg); curl_easy_setopt(curl, CURLOPT_POST, 1L); From c5da49255f22032fb24161b026c55d41a41688bf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 23 Nov 2025 16:01:19 +0000 Subject: [PATCH 04/12] Update build documentation for libcurl dependency Co-authored-by: ckrause <840744+ckrause@users.noreply.github.com> --- src/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/README.md b/src/README.md index 0c5642b0..341812a0 100644 --- a/src/README.md +++ b/src/README.md @@ -17,7 +17,13 @@ The C++ source code contain is organized into the following modules: ## Building -LODA supports Linux, macOS, and Windows. You need a standard C++ compiler and `make` (or `nmake` on Windows). No external libraries are required, but the `curl` and `gzip` command-line tools must be available. +LODA supports Linux, macOS, and Windows. You need a standard C++ compiler and `make` (or `nmake` on Windows). The `libcurl` development library and the `gzip` command-line tool must be available at build time. + +### Build Dependencies + +- **C++ compiler**: g++, clang++, or MSVC (C++17 support required) +- **libcurl**: Development headers and library (e.g., `libcurl4-openssl-dev` on Debian/Ubuntu) +- **gzip**: Command-line tool for compression To build from source, switch to the `src/` folder and run the appropriate command for your platform: From 8e3e3efc2079754b954721f39cef42cc8a2ea796 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 23 Nov 2025 18:45:06 +0000 Subject: [PATCH 05/12] Add libcurl installation to GitHub workflows Co-authored-by: ckrause <840744+ckrause@users.noreply.github.com> --- .github/workflows/main.yml | 16 +++++++++++++++- .github/workflows/release.yml | 14 ++++++++++++++ src/Makefile.windows.mk | 7 +++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6f201f03..9c5b1909 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,6 +12,8 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev - name: Build run: cd src && make -f Makefile.linux-x86.mk - name: Install external tools @@ -32,6 +34,8 @@ jobs: runs-on: ubuntu-24.04-arm steps: - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev - name: Build run: cd src && make -f Makefile.linux-arm64.mk - name: Test @@ -57,8 +61,13 @@ jobs: steps: - uses: actions/checkout@v2 - uses: ilammy/msvc-dev-cmd@v1 + - name: Install dependencies + run: | + vcpkg install curl:x64-windows - name: Build run: cd src && nmake.exe /F Makefile.windows.mk + env: + VCPKG_ROOT: C:\vcpkg - name: Test run: ./loda.exe test build-windows-arm64: @@ -68,14 +77,19 @@ jobs: - uses: ilammy/msvc-dev-cmd@v1 with: arch: amd64_arm64 + - name: Install dependencies + run: | + vcpkg install curl:arm64-windows - name: Build run: cd src && nmake.exe /F Makefile.windows.mk + env: + VCPKG_ROOT: C:\vcpkg code-coverage: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 - name: Generate - run: sudo apt install lcov && cd src && make -f Makefile.linux-x86.mk coverage + run: sudo apt-get update && sudo apt-get install -y lcov libcurl4-openssl-dev && cd src && make -f Makefile.linux-x86.mk coverage - name: Upload uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b14e7ec3..cea66a67 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,6 +44,8 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev - name: Build run: cd src && make -f Makefile.linux-x86.mk loda LODA_PLATFORM=linux-x86 LODA_VERSION=${{ needs.create-release.outputs.version }} - name: Upload @@ -60,6 +62,8 @@ jobs: runs-on: ubuntu-24.04-arm steps: - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev - name: Build run: cd src && make -f Makefile.linux-arm64.mk loda LODA_PLATFORM=linux-arm64 LODA_VERSION=${{ needs.create-release.outputs.version }} - name: Upload @@ -109,8 +113,13 @@ jobs: steps: - uses: actions/checkout@v2 - uses: ilammy/msvc-dev-cmd@v1 + - name: Install dependencies + run: | + vcpkg install curl:x64-windows - name: Build run: cd src && nmake.exe /F Makefile.windows.mk loda LODA_PLATFORM=windows-x86 LODA_VERSION=${{ needs.create-release.outputs.version }} + env: + VCPKG_ROOT: C:\vcpkg - name: Upload uses: actions/upload-release-asset@v1 with: @@ -128,8 +137,13 @@ jobs: - uses: ilammy/msvc-dev-cmd@v1 with: arch: amd64_arm64 + - name: Install dependencies + run: | + vcpkg install curl:arm64-windows - name: Build run: cd src && nmake.exe /F Makefile.windows.mk loda LODA_PLATFORM=windows-arm64 LODA_VERSION=${{ needs.create-release.outputs.version }} + env: + VCPKG_ROOT: C:\vcpkg - name: Upload uses: actions/upload-release-asset@v1 with: diff --git a/src/Makefile.windows.mk b/src/Makefile.windows.mk index ea10c94c..264ed1d9 100644 --- a/src/Makefile.windows.mk +++ b/src/Makefile.windows.mk @@ -1,5 +1,12 @@ CXXFLAGS = /I. /std:c++17 /O2 /GL LDFLAGS = /link /LTCG + +# Check if VCPKG_ROOT is set (for vcpkg integration) +!IFDEF VCPKG_ROOT +CXXFLAGS = $(CXXFLAGS) /I$(VCPKG_ROOT)\installed\x64-windows\include +LDFLAGS = $(LDFLAGS) /LIBPATH:$(VCPKG_ROOT)\installed\x64-windows\lib +!ENDIF + CURL_LIBS = libcurl.lib !IFDEF LODA_VERSION From c62d4e58d4699af01e38c3f1393447f40565410a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 23 Nov 2025 18:49:21 +0000 Subject: [PATCH 06/12] Fix vcpkg architecture handling and improve workflow readability Co-authored-by: ckrause <840744+ckrause@users.noreply.github.com> --- .github/workflows/main.yml | 5 ++++- .github/workflows/release.yml | 1 + src/Makefile.windows.mk | 8 ++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9c5b1909..218247b1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -84,12 +84,15 @@ jobs: run: cd src && nmake.exe /F Makefile.windows.mk env: VCPKG_ROOT: C:\vcpkg + VCPKG_ARCH: arm64-windows code-coverage: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y lcov libcurl4-openssl-dev - name: Generate - run: sudo apt-get update && sudo apt-get install -y lcov libcurl4-openssl-dev && cd src && make -f Makefile.linux-x86.mk coverage + run: cd src && make -f Makefile.linux-x86.mk coverage - name: Upload uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cea66a67..b472b229 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -144,6 +144,7 @@ jobs: run: cd src && nmake.exe /F Makefile.windows.mk loda LODA_PLATFORM=windows-arm64 LODA_VERSION=${{ needs.create-release.outputs.version }} env: VCPKG_ROOT: C:\vcpkg + VCPKG_ARCH: arm64-windows - name: Upload uses: actions/upload-release-asset@v1 with: diff --git a/src/Makefile.windows.mk b/src/Makefile.windows.mk index 264ed1d9..97525ef7 100644 --- a/src/Makefile.windows.mk +++ b/src/Makefile.windows.mk @@ -3,8 +3,12 @@ LDFLAGS = /link /LTCG # Check if VCPKG_ROOT is set (for vcpkg integration) !IFDEF VCPKG_ROOT -CXXFLAGS = $(CXXFLAGS) /I$(VCPKG_ROOT)\installed\x64-windows\include -LDFLAGS = $(LDFLAGS) /LIBPATH:$(VCPKG_ROOT)\installed\x64-windows\lib +# Default to x64-windows if VCPKG_ARCH is not specified +!IFNDEF VCPKG_ARCH +VCPKG_ARCH = x64-windows +!ENDIF +CXXFLAGS = $(CXXFLAGS) /I$(VCPKG_ROOT)\installed\$(VCPKG_ARCH)\include +LDFLAGS = $(LDFLAGS) /LIBPATH:$(VCPKG_ROOT)\installed\$(VCPKG_ARCH)\lib !ENDIF CURL_LIBS = libcurl.lib From c7f63ca32c18c8aae898ae35d802487f37538162 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 23 Nov 2025 19:08:51 +0000 Subject: [PATCH 07/12] Fix Windows build by undefining ERROR macro from curl headers Co-authored-by: ckrause <840744+ckrause@users.noreply.github.com> --- src/sys/web_client.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sys/web_client.cpp b/src/sys/web_client.cpp index a8353a02..172f6c1e 100644 --- a/src/sys/web_client.cpp +++ b/src/sys/web_client.cpp @@ -5,6 +5,11 @@ #include +// Undefine Windows macros that conflict with our code +#ifdef ERROR +#undef ERROR +#endif + #include "sys/file.hpp" #include "sys/log.hpp" From b7388dbc4c2b95b1cca0b14b494f48a23bc88df0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 28 Nov 2025 19:08:01 +0000 Subject: [PATCH 08/12] Add linked libraries display after build in Makefile and Makefile.windows.mk Co-authored-by: ckrause <840744+ckrause@users.noreply.github.com> --- src/Makefile | 2 ++ src/Makefile.windows.mk | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Makefile b/src/Makefile index 4be09fe8..b3bd1c07 100644 --- a/src/Makefile +++ b/src/Makefile @@ -27,6 +27,8 @@ loda: $(OBJS) $(CXX) $(LDFLAGS) -o loda $(OBJS) $(CURL_LIBS) [ -L ../loda ] || ( cd .. && ln -s src/loda loda ) du -sh loda + @echo "Linked libraries:" + @ldd loda 2>/dev/null || otool -L loda 2>/dev/null || echo "Unable to determine linked libraries" coverage: CXXFLAGS += -O0 -fprofile-arcs -ftest-coverage coverage: LDFLAGS += --coverage diff --git a/src/Makefile.windows.mk b/src/Makefile.windows.mk index 97525ef7..8f4433eb 100644 --- a/src/Makefile.windows.mk +++ b/src/Makefile.windows.mk @@ -37,6 +37,8 @@ SRCS = base/uid.cpp \ loda: $(SRCS) cl /EHsc /Feloda.exe $(CXXFLAGS) $(SRCS) $(LDFLAGS) $(CURL_LIBS) copy loda.exe .. + @echo Linked libraries: + dumpbin /dependents loda.exe clean: del /f $(OBJS) loda.exe ../loda.exe From 5e50e87fa640c0ea6b1cc2c6c48c14907ccf699c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 18:13:21 +0000 Subject: [PATCH 09/12] Package Windows releases as zip files with loda.exe and libcurl.dll Co-authored-by: ckrause <840744+ckrause@users.noreply.github.com> --- .github/workflows/release.yml | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b472b229..e72d88bc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -120,13 +120,20 @@ jobs: run: cd src && nmake.exe /F Makefile.windows.mk loda LODA_PLATFORM=windows-x86 LODA_VERSION=${{ needs.create-release.outputs.version }} env: VCPKG_ROOT: C:\vcpkg + - name: Package + run: | + mkdir loda-windows-x86 + copy loda.exe loda-windows-x86\ + copy C:\vcpkg\installed\x64-windows\bin\libcurl.dll loda-windows-x86\ + Compress-Archive -Path loda-windows-x86\* -DestinationPath loda-windows-x86.zip + shell: pwsh - name: Upload uses: actions/upload-release-asset@v1 with: upload_url: ${{ needs.create-release.outputs.upload_url }} - asset_path: ./loda.exe - asset_name: loda-windows-x86.exe - asset_content_type: application/octet-stream + asset_path: ./loda-windows-x86.zip + asset_name: loda-windows-x86.zip + asset_content_type: application/zip env: GITHUB_TOKEN: ${{ github.token }} build-windows-arm64: @@ -145,12 +152,19 @@ jobs: env: VCPKG_ROOT: C:\vcpkg VCPKG_ARCH: arm64-windows + - name: Package + run: | + mkdir loda-windows-arm64 + copy loda.exe loda-windows-arm64\ + copy C:\vcpkg\installed\arm64-windows\bin\libcurl.dll loda-windows-arm64\ + Compress-Archive -Path loda-windows-arm64\* -DestinationPath loda-windows-arm64.zip + shell: pwsh - name: Upload uses: actions/upload-release-asset@v1 with: upload_url: ${{ needs.create-release.outputs.upload_url }} - asset_path: ./loda.exe - asset_name: loda-windows-arm64.exe - asset_content_type: application/octet-stream + asset_path: ./loda-windows-arm64.zip + asset_name: loda-windows-arm64.zip + asset_content_type: application/zip env: GITHUB_TOKEN: ${{ github.token }} From d5eb62fbf4e45cb3235372ba64932fe45b0bae5b Mon Sep 17 00:00:00 2001 From: Christian Krause Date: Sat, 29 Nov 2025 19:29:56 +0100 Subject: [PATCH 10/12] update makefiles --- src/Makefile | 2 -- src/Makefile.windows.mk | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/Makefile b/src/Makefile index b3bd1c07..4be09fe8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -27,8 +27,6 @@ loda: $(OBJS) $(CXX) $(LDFLAGS) -o loda $(OBJS) $(CURL_LIBS) [ -L ../loda ] || ( cd .. && ln -s src/loda loda ) du -sh loda - @echo "Linked libraries:" - @ldd loda 2>/dev/null || otool -L loda 2>/dev/null || echo "Unable to determine linked libraries" coverage: CXXFLAGS += -O0 -fprofile-arcs -ftest-coverage coverage: LDFLAGS += --coverage diff --git a/src/Makefile.windows.mk b/src/Makefile.windows.mk index 8f4433eb..97525ef7 100644 --- a/src/Makefile.windows.mk +++ b/src/Makefile.windows.mk @@ -37,8 +37,6 @@ SRCS = base/uid.cpp \ loda: $(SRCS) cl /EHsc /Feloda.exe $(CXXFLAGS) $(SRCS) $(LDFLAGS) $(CURL_LIBS) copy loda.exe .. - @echo Linked libraries: - dumpbin /dependents loda.exe clean: del /f $(OBJS) loda.exe ../loda.exe From 98cfee2b94425834021fb280bb29451cebedef68 Mon Sep 17 00:00:00 2001 From: Christian Krause Date: Sat, 29 Nov 2025 19:31:07 +0100 Subject: [PATCH 11/12] update changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcdb2f9a..1d338a45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## [Unreleased] +### Enhancements + +* Integrate `libcurl` for HTTP requests, replacing external `curl`/`wget` tools + ## v25.11.29 ### Enhancements @@ -16,7 +20,6 @@ * Use `v2/submissions/` API endpoint to fetch and submit programs * Handle program submissions with `delete` mode -* Integrate libcurl for HTTP requests, replacing external curl/wget tools ## v25.11.9 From b7d2efbe74f530d9452839c0992772481198d522 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 18:57:18 +0000 Subject: [PATCH 12/12] Restore pthread linker flags to prevent segmentation faults Co-authored-by: ckrause <840744+ckrause@users.noreply.github.com> --- src/Makefile.linux-arm64.mk | 2 +- src/Makefile.linux-x86.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.linux-arm64.mk b/src/Makefile.linux-arm64.mk index 5aae0303..3596fe59 100644 --- a/src/Makefile.linux-arm64.mk +++ b/src/Makefile.linux-arm64.mk @@ -2,7 +2,7 @@ # see https://stackoverflow.com/questions/35116327/when-g-static-link-pthread-cause-segmentation-fault-why CXX = aarch64-linux-gnu-g++ CXXFLAGS += -pthread -flto=auto -LDFLAGS = -static-libstdc++ -static-libgcc -pthread -s -flto=auto +LDFLAGS = -static-libstdc++ -static-libgcc -lrt -pthread -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -s -flto=auto CURL_LIBS = -lcurl # END PLATFORM CONFIG FOR LINUX ARM64 diff --git a/src/Makefile.linux-x86.mk b/src/Makefile.linux-x86.mk index 0ed81abc..a45044ca 100644 --- a/src/Makefile.linux-x86.mk +++ b/src/Makefile.linux-x86.mk @@ -2,7 +2,7 @@ # see https://stackoverflow.com/questions/35116327/when-g-static-link-pthread-cause-segmentation-fault-why CXX = x86_64-linux-gnu-g++ CXXFLAGS += -pthread -flto=auto -LDFLAGS = -static-libstdc++ -static-libgcc -pthread -s -flto=auto +LDFLAGS = -static-libstdc++ -static-libgcc -lrt -pthread -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -s -flto=auto CURL_LIBS = -lcurl # END PLATFORM CONFIG FOR LINUX X86