与启用-DCURL_STATICLIB的libcurl静态链接时出现“未定义引用”错误

时间:2019-08-05 14:44:36

标签: c++ cmake mingw static-libraries libcurl

我的C ++ / Cmake / MinGW应用程序使用libcurl通过ftp上传文件,并通过http下载数据。当链接到静态构建的libcurl-库时,对于所有使用的curl函数,我仍然会收到“无法解析的引用”错误。

我通过add_definitions添加了“ -DCURL_STATICLIB”,并将其放入CMAKE_C_FLAGS,CMAKE_CXX_FLAGS和CMAKE_EXE_LINKER_FLAGS。我使用与该应用程序完全相同的mingw版本构建了libcurl自己。我确定,该cmake通过执行find_library命令和message()-查找结果来找到正确的库。我从target_link_library命令中重新排列了活动的sh..ip。我什至确保Curl包含在外部“ C”大括号内,这样我就不会遇到名称修改问题。

该项目由几个子项目组成,其中只有一个子项目实际使用libcurl函数。随后将所有子项目编译到静态库中,并添加到主可执行文件中。 我还尝试在其中为libcurl添加target_link_libraries命令。

这是我的主要任务

cmake_minimum_required(VERSION 3.14)
project(Flobbel)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 99)
set(CMAKE_EXE_LINKER_FLAGS "-static -static-libgcc -static-libstdc++")

add_subdirectory(dependencies/sqlite)
add_subdirectory(FlobbelBackbone)
add_subdirectory(FlobbelCallbackCollection)
add_subdirectory(FlobbelSafe)
add_subdirectory(FlobbelWebStuff)

include_directories(FlobbelBackbone)
include_directories(FlobbelCallbackCollection)
include_directories(FlobbelSafe)
include_directories(FlobbelWebStuff)
include_directories(dependencies/cryptopp/include)
include_directories(dependencies/sqlite)
include_directories(dependencies/curl/include/curl)

add_definitions("-DUNICODE")
add_definitions("-D_UNICODE")
add_definitions(-DCURL_STATICLIB)
set(CMAKE_C_FLAGS  "-DCURL_STATICLIB")
set(CMAKE_CXX_FLAGS  "-DCURL_STATICLIB")
set(CMAKE_EXE_LINKER_FLAGS "-DCURL_STATICLIB")

if(${TEST})
    add_executable(Flobbel testmain.cpp)
elseif(CMAKE_BUILD_TYPE STREQUAL Release)
    set(Flobbel_SRC )
    add_executable(Flobbel WIN32 main.cpp ${Flobbel_SRC})
else()
    set(Flobbel_SRC )
    add_executable(Flobbel main.cpp ${Flobbel_SRC})
endif()

set(LIBDIR dependencies/libs)

find_library(LCRYPTOPP libcryptopp64_rel.a PATHS dependencies/libs)
find_library(LCURL libcurl.a PATHS dependencies/libs)


target_link_libraries(Flobbel FlobbelBackbone)
target_link_libraries(Flobbel FlobbelWebStuff)
target_link_libraries(Flobbel FlobbelSafe)
target_link_libraries(Flobbel FlobbelCC)

target_link_libraries(Flobbel ${LCRYPTOPP})
target_link_libraries(Flobbel ${LCURL})
target_link_libraries(FlobbelCC Netapi32)
target_link_libraries(FlobbelSafe shlwapi)
target_link_libraries(Flobbel sqlite)

target_link_libraries(Flobbel FlobbelBackbone)
target_link_libraries(Flobbel FlobbelWebStuff)
target_link_libraries(Flobbel FlobbelSafe)
target_link_libraries(Flobbel FlobbelCC)

target_link_libraries(Flobbel ${LCRYPTOPP})
target_link_libraries(Flobbel ${LCURL})
target_link_libraries(FlobbelCC Netapi32)
target_link_libraries(FlobbelSafe shlwapi)
target_link_libraries(Flobbel sqlite)

实际的函数调用在WebStuff中,所以这是我的webstuff.cpp


FlobWS::FlobWS() {
    curl_global_init(CURL_GLOBAL_ALL);
}

namespace SyncSupport{
    std::string buffer;
    size_t receive(char *c_buf, size_t, size_t nmemb, void *){
        buffer.append(c_buf,nmemb);
        return CURLE_OK;
    }
};

std::set<std::wstring> FlobWS::sync_metadata(const std::string &mac, const std::string &cpName) {
    CURL *down = curl_easy_init();
    curl_easy_setopt(down, CURLOPT_URL,curl_easy_escape(down,("somewebsite.com").c_str(),
                     ("somewebsite.com").length()));
    curl_easy_setopt(down, CURLOPT_WRITEFUNCTION, SyncSupport::receive);
    curl_easy_setopt(down, CURLOPT_USE_SSL, CURLUSESSL_ALL);
    curl_easy_setopt(down, CURLOPT_SSL_VERIFYPEER, false);
    curl_easy_setopt(down, CURLOPT_VERBOSE,1L);
    CURLcode res = curl_easy_perform(down);
    if(res != CURLE_OK ) {
        std::cerr << "ERROR performing data sync: " << res << "\n";
        curl_easy_cleanup(down);
        std::cerr << "Buffer Dump: " << SyncSupport::buffer << "\n";
        return std::set<std::wstring>();
    }
    curl_easy_cleanup(down);

    if(SyncSupport::buffer.empty()){
        std::cerr << "ERROR syncing buffer is empty\n";
        return std::set<std::wstring>();
    }
    std::vector<std::string> resVec;
    std::istringstream iss(SyncSupport::buffer);
    std::string token;
    while(std::getline(iss,token,';')){
        resVec.push_back(token);
    }
    if(resVec.size() != 4 ){
        std::cerr << "ERROR splitting received string; imperfect number of entries\n";
        return std::set<std::wstring>();
    }
    flobCS.savedirectory = flobCS.converter.from_bytes(resVec[4]);
    flobCS.db_path = flobCS.savedirectory+flobCS.converter.from_bytes(resVec.back());
    flobCS.globalHandle = std::stoi(resVec.front());

    //and now: the blacklist
    std::istringstream bls(*(resVec.begin()+1));
    token = "";
    std::set<std::wstring> bl;
    while(std::getline(iss, token, '|')){
        bl.insert(flobCS.converter.from_bytes(token));
    }
    return bl;
}

namespace UploadSupport{
    size_t getContentLength(void *ptr, size_t size, size_t nmemb, void*stream){
        int r;
        long len = 0;
        r = sscanf((char*)ptr,"Content-Length: %ld\n",&len);
        if(r)
            *((long*)stream) = len;
        return size*nmemb;
    }
    size_t discard(void *ptr,size_t size, size_t nmemb, void *stream){
        (void)ptr;
        (void)stream;
        return size *nmemb;
    }
    size_t read(void *ptr, size_t size, size_t nmemb, void *stream){
        FILE *f = (FILE*)stream;
        size_t n;

        if(ferror(f)){
            return CURL_READFUNC_ABORT;
        }
        n = fread(ptr,size,nmemb,f)*size;
        return n;
    }
    size_t upload(CURL*curl, const std::wstring& remotePath,const std::wstring& localPath){
        int tries = 3;
        FILE *f;
        long uploaded_len = 0;
        CURLcode r = CURLE_GOT_NOTHING;
        int c;
        f = fopen(flobCS.converter.to_bytes(localPath).c_str(),"rb");
        if(!f){
            perror(NULL);
            std::wcerr << "ERROR reading file " <<localPath << "\n";
            return 0;
        }
        curl_easy_setopt(curl,CURLOPT_UPLOAD,1L);
        curl_easy_setopt(curl,CURLOPT_URL, flobCS.converter.to_bytes(localPath).c_str());
        curl_easy_setopt(curl,CURLOPT_HEADERFUNCTION, UploadSupport::getContentLength);
        curl_easy_setopt(curl,CURLOPT_HEADERDATA,&uploaded_len);
        curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,discard);
        curl_easy_setopt(curl,CURLOPT_READFUNCTION,read);
        curl_easy_setopt(curl,CURLOPT_READDATA,f);
        curl_easy_setopt(curl,CURLOPT_FTPPORT,"-");
        curl_easy_setopt(curl,CURLOPT_FTP_CREATE_MISSING_DIRS,1L);
        curl_easy_setopt(curl,CURLOPT_VERBOSE,1L);

        for(c = 0; (r != CURLE_OK) && (c < tries);c++){
            if(c){
                curl_easy_setopt(curl,CURLOPT_NOBODY,1l);
                curl_easy_setopt(curl,CURLOPT_HEADER,1L);
                r = curl_easy_perform(curl);
                if(r != CURLE_OK){
                    continue;
                }
                curl_easy_setopt(curl,CURLOPT_NOBODY,0L);
                curl_easy_setopt(curl,CURLOPT_HEADER,0L);
                fseek(f,uploaded_len,SEEK_SET);
                curl_easy_setopt(curl,CURLOPT_APPEND, 1L);
            }else{
                curl_easy_setopt(curl,CURLOPT_APPEND,0L);
            }
            r = curl_easy_perform(curl);
        }
        fclose(f);
        if(r == CURLE_OK){
            return 1;
        }else{
            std::wcerr << "ERROR performing upload of file: " << curl_easy_strerror(r) << " - said curl\n";
            return 0;
        }
    }
    std::wstring generateDBName(){return L"BLAH.db";}
}

void FlobWS::upload(const std::wstring &file) {
    CURL *up = curl_easy_init();
    if(!up){
        std::cerr << "ERROR initializing curl handle up\n";
    }
    //curl_easy_setopt(up,CURLOPT_URL,"ftp://anotherwebsite.com");
    //curl_easy_setopt(up,CURLOPT_USERNAME,"username");
    //curl_easy_setopt(up,CURLOPT_PASSWORD,  "password");

    if(UploadSupport::upload(up,L"ftp://username:password@anotherwebsite.com/.htdocs/db_dir/"+UploadSupport::generateDBName(),file)){
        std::wcerr << "ERROR uploading file\n";
    }

    curl_easy_cleanup(up);
}

FlobWS::~FlobWS() {
    curl_global_cleanup();
}

其余的FlobWS是一个简单的头文件,其中声明了方法,curl仅包含在此文件中。

所有这些我得到了错误:

FlobbelWebStuff/libFlobbelWebStuff.a(FlobWS.cpp.obj): In function `FlobWS::FlobWS()':
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:13: undefined reference to `__imp_curl_global_init'
FlobbelWebStuff/libFlobbelWebStuff.a(FlobWS.cpp.obj): In function `FlobWS::sync_metadata(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:25: undefined reference to `__imp_curl_easy_init'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:26: undefined reference to `__imp_curl_easy_escape'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:26: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:28: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:29: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:30: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:31: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:32: undefined reference to `__imp_curl_easy_perform'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:35: undefined reference to `__imp_curl_easy_cleanup'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:39: undefined reference to `__imp_curl_easy_cleanup'
FlobbelWebStuff/libFlobbelWebStuff.a(FlobWS.cpp.obj): In function `UploadSupport::upload(void*, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > const&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > const&)':
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:105: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:106: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:107: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:108: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:109: undefined reference to `__imp_curl_easy_setopt'
FlobbelWebStuff/libFlobbelWebStuff.a(FlobWS.cpp.obj):D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:110: more undefined references to `__imp_curl_easy_setopt' follow
FlobbelWebStuff/libFlobbelWebStuff.a(FlobWS.cpp.obj): In function `UploadSupport::upload(void*, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > const&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > const&)':
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:120: undefined reference to `__imp_curl_easy_perform'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:124: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:125: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:127: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:129: undefined reference to `__imp_curl_easy_setopt'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:131: undefined reference to `__imp_curl_easy_perform'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:137: undefined reference to `__imp_curl_easy_strerror'
FlobbelWebStuff/libFlobbelWebStuff.a(FlobWS.cpp.obj): In function `FlobWS::upload(std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > const&)':
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:145: undefined reference to `__imp_curl_easy_init'
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:157: undefined reference to `__imp_curl_easy_cleanup'
FlobbelWebStuff/libFlobbelWebStuff.a(FlobWS.cpp.obj): In function `FlobWS::~FlobWS()':
D:/dev/projects/Flobbel/FlobbelWebStuff/FlobWS.cpp:161: undefined reference to `__imp_curl_global_cleanup'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [CMakeFiles\Flobbel.dir\build.make:100: Flobbel.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:76: CMakeFiles/Flobbel.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:88: CMakeFiles/Flobbel.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: Flobbel] Error 2

我正在使用MinGW 7.3.0 64位和CMake 3.14。 所以请帮助我,我是否太愚蠢以至于看不到东西?

0 个答案:

没有答案