简体   繁体   中英

How to link curl to a program so I can run it on another machine?

I'm trying to link curl to a program in CodeBlocks and then run it on another PC with Windows. If I set environmental variable %PATH% everything works fine, however if I remove it an error appears saying libcurl-x64.dll not found .

To fix that I tried following:

  • linking libcurl.dll.a and libcurl.a with Linker settings in Bulid Options and Compiler both x64 and x86 versions,
  • adding ..\curl-7.86.0_2-win/*(32/64)*/-mingw\include to Search directories in Bulid Options and Compiler
  • writing -lcurl , -static-lcurl , -DCURL_STATICLIB -lcurl , -lws2_32 and -lwinmm in every variations that would make sense.

However the same error still appears. How can l fix it?
CB Project file:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
    <FileVersion major="1" minor="6" />
    <Project>
        <Option title="download" />
        <Option pch_mode="2" />
        <Option compiler="gcc" />
        <Build>
            <Target title="Debug">
                <Option output="bin/Debug/download" prefix_auto="1" extension_auto="1" />
                <Option object_output="obj/Debug/" />
                <Option type="1" />
                <Option compiler="gcc" />
                <Compiler>
                    <Add option="-g" />
                    <Add directory="C:/libs/curl-7.86.0_2-win32-mingw/include" />
                    <Add directory="C:/libs/curl-7.86.0_2-win64-mingw/include" />
                </Compiler>
                <Linker>
                    <Add library="C:/libs/curl-7.86.0_2-win32-mingw/lib/libcurl.dll.a" />
                    <Add library="C:/libs/curl-7.86.0_2-win64-mingw/lib/libcurl.dll.a" />
                    <Add directory="C:/libs/curl-7.86.0_2-win32-mingw/lib" />
                    <Add directory="C:/libs/curl-7.86.0_2-win64-mingw/lib" />
                </Linker>
            </Target>
            <Target title="Release">
                <Option output="bin/Release/download" prefix_auto="1" extension_auto="1" />
                <Option object_output="obj/Release/" />
                <Option type="1" />
                <Option compiler="gcc" />
                <Compiler>
                    <Add option="-O2" />
                </Compiler>
                <Linker>
                    <Add option="-s" />
                </Linker>
            </Target>
        </Build>
        <Compiler>
            <Add option="-Wall" />
            <Add option="-fexceptions" />
            <Add directory="C:/libs/curl-7.86.0_2-win32-mingw/include" />
            <Add directory="C:/libs/curl-7.86.0_2-win64-mingw/include" />
        </Compiler>
        <Linker>
            <Add option="-lcurl -lwinmm -static" />
            <Add library="C:/libs/curl-7.86.0_2-win64-mingw/lib/libcurl.a" />
            <Add library="C:/libs/curl-7.86.0_2-win32-mingw/lib/libcurl.a" />
            <Add library="C:/libs/curl-7.86.0_2-win32-mingw/lib/libcurl.dll.a" />
            <Add library="C:/libs/curl-7.86.0_2-win64-mingw/lib/libcurl.dll.a" />
            <Add directory="C:/libs/curl-7.86.0_2-win32-mingw/lib" />
            <Add directory="C:/libs/curl-7.86.0_2-win64-mingw/lib" />
        </Linker>
        <Unit filename="main.cpp" />
        <Extensions>
            <lib_finder disable_auto="1" />
        </Extensions>
    </Project>
</CodeBlocks_project_file>

Some people call this "DLL hell", as it can be hard to figure out if you're new to this.

But there are multiple solutions:

Static build

You could build a static executable using linker flag -static . However this also requires linking with all the dependencies of your dependencies, etc...

This can be hard to do as MinGW requires the -l to be in the right order too.

Also, you may still have dependencies on the standard library, so you may also need to add -static-libgcc (for C) or -static-libstdc++ (for C++).

If you get your dependency linker flags with pkg-config you can use the pkg-config --static --libs to list the static dependencies.

Note that you can actually use pkg-config in Code::Blocks linker flags if you surround it with back-quotes.

The advantage of a static build is that you only need to distribute the .exe file(s).

Shared build

If you do a shared build (which is the case by default, but there is a -shared linker flag) your .exe file(s) will depend on the .dll files of the program's dependencies, and these .dll files will depend on the .dll files of their dependencies, etc...

But if you copy all the .dll files in the same folder as the .exe file(s) you can distribute your application and it will run on other systems.

Since the .dll files are in the same folder as the .exe file(s) Windows will pick them up there and there is no need to point to their location using the PATH environment variable.

Copying all the right .dll files can be a challenge though, so I have written a tool to detect which .dll files .exe files depend on and copies those files. The tool is available here: https://github.com/brechtsanders/pedeps

To copy an .exe file with all .dll files it needs you need to run copypedeps with the -r flag (to recurse through each dependency).

For example you have a file hello.exe in the current folder and you want to copy it along with all its dependencies to the folder dist run the following command:

copypedeps -r hello.exe dist

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM