libcpr / cpr

C++ Requests: Curl for People, a spiritual port of Python Requests.
https://docs.libcpr.org/
Other
6.44k stars 917 forks source link

C++20 ixx Module | unresolved external symbol _Cnd_timedwait_for #1080

Closed TheHellTower closed 1 month ago

TheHellTower commented 1 month ago

Description

Whenever I use cpr into my ixx module I just get an LNK2001 unresolved external symbol _Cnd_timedwait_for and can't build my project.

Build started at 5:37 PM...
1>------ Build started: Project: Tools, Configuration: Release x64 ------
1>Scanning sources for module dependencies...
1>cpr.lib(threadpool.cpp.obj) : error LNK2001: unresolved external symbol _Cnd_timedwait_for
1>Tools.exe : fatal error LNK1120: 1 unresolved externals
1>Done building project "Tools.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 5:37 PM and took 00.385 seconds ==========

When I comment the return lines in sendRequest it compiles.. But I need the response..

Example/How to Reproduce

Create an ixx(C++20) Module with the following code:

export module Req;
import <string>;
import <unordered_map>;
import <cpr/cpr.h>;

namespace Req {
    enum class Method {
        GET,
        POST
    };

    static constexpr const char* baseURL = "https://example.com";

    class Request {
    public:
        Request(Method method, const std::string& endpoint)
            : method_(method), endpoint_(endpoint) {}

        void addHeader(const std::string& key, const std::string& value) {
            headers_[key] = value;
        }

        void addFormData(const std::string& key, const std::string& value) {
            formData_[key] = value;
        }

        cpr::Response sendRequest() const {
            cpr::Url url = cpr::Url{ baseURL + endpoint_ };

            if (method_ == Method::GET) {
                url = addParametersToUrl(url);
                return cpr::Get(url, buildRequestOptions());
            }
            else if (method_ == Method::POST) {
                cpr::Parameters parameters;
                for (const auto& pair : formData_) {
                    parameters.Add({ pair.first, pair.second });
                }
                return cpr::Post(url, buildRequestOptions(), parameters);
            }

            // Default to GET if method is invalid
            return cpr::Get(url, buildRequestOptions());
        }

    private:
        Method method_;
        std::string endpoint_;
        std::unordered_map<std::string, std::string> headers_;
        std::unordered_map<std::string, std::string> formData_;

        cpr::Url addParametersToUrl(const cpr::Url& url) const {
            // Implement parameter handling logic if needed
            return url;
        }

        cpr::Header buildRequestOptions() const {
            cpr::Header options;
            for (const auto& pair : headers_) {
                options.insert({ pair.first, pair.second });
            }
            return options;
        }
    };
}

Possible Fix

No response

Where did you get it from?

vcpkg

Additional Context/Your Environment

TheHellTower commented 1 month ago

I for some reasons even have this issue with very minimal example:

#include <iostream>
#include <cpr/cpr.h>

int main()
{
    cpr::Response response = cpr::Get(cpr::Url{ "https://example.com" });
    std::cout << response.text << std::endl;
}

Is the vcpkg package broken ? Reinstall it didn't really help..

- vcpkg remove cpr:x64-windows --recurse
- vcpkg install cpr:x64-windows 
COM8 commented 1 month ago

@TheHellTower thanks for reporting. To me this looks like a vcpkg/msvc issue? I tested it on Linux using gcc 14.1.1 where everything worked except the import std; (need to wait for gcc 15 for that :) ). Clang had other include related issues.

Here is my code: https://github.com/libcpr/example-cmake-fetch-content/tree/feature/cpr_module

TheHellTower commented 1 month ago

@TheHellTower thanks for reporting. To me this looks like a vcpkg/msvc issue? I tested it on Linux using gcc 14.1.1 where everything worked except the import std; (need to wait for gcc 15 for that :) ). Clang had other include related issues.

Here is my code: https://github.com/libcpr/example-cmake-fetch-content/tree/feature/cpr_module

Hello, yes I'm using Visual Studio and the MSVC compiler, but I never got this issue before it happened after I completelly replace vcpkg.. Do you have any idea ? Because even the very simple example with only a simple GET request in the main function fail.. Do I need to open an issue on the vcpkg repository and mention this issue ?

COM8 commented 1 month ago

Sorry there I can not help you. From the cpr side of things everything looks to be working at least on Linux.

Since I recognize the location your error is showing up, it could be a missing linker directive.

I'm not sure what needs to be done to link against this missing function on Windows since I suspect it should be part of #include <mutex> also on Windows.

https://github.com/microsoft/STL/blob/main/stl/src/sharedmutex.cpp

TheHellTower commented 1 month ago

Sorry there I can not help you. From the cpr side of things everything looks to be working at least on Linux.

Since I recognize the location your error is showing up, it could be a missing linker directive.

I'm not sure what needs to be done to link against this missing function on Windows since I suspect it should be part of #include <mutex> also on Windows.

https://github.com/microsoft/STL/blob/main/stl/src/sharedmutex.cpp

Yeah I found this definition only in STL repository and so I wasn't sure how it was part of cpr.. Sadly even with this include the same error happens.. I will open an issue on the vcpkg repository to see if they have an idea about the issue, thanks !

TheHellTower commented 1 month ago

So I seen on the readme that CPR got a NuGet package and:

NuGet Package: Compile VCPKG Build: LNK2001 unresolved external symbol _Cnd_timedwait_for

So I think the it can be a VCPKG issue 🤔

COM8 commented 1 month ago

Closing this one since it does not look to be a cpr issue.