How do I embed a binary executable (to be executed at runtime) in a Qt program?

前端 未结 4 1002
南方客
南方客 2020-12-03 19:17

I\'m writing a cross-platform C++ program using Qt and I want to package/embed a number of binary executables within the program. The program should be able to execute these

相关标签:
4条回答
  • 2020-12-03 19:20

    You can't execute a program directly from a resource.

    If you had a program in a resource and you wanted to execute it, you'd first have to read it out of the resource, write it to a file, make the file executable, then execute it.

    Also, when you say that you're not getting an error, that probably means that you aren't checking for errors properly.

    0 讨论(0)
  • 2020-12-03 19:23

    So the problem doesn't seem to be extracting the git executable from the resource so much as executing it?

    The git program is generate don disk correctly, can you check it's permissions ?

    0 讨论(0)
  • 2020-12-03 19:27

    Several years late, but the question is still relevant. I had the same problem when wanting to embed rclone.

    In the .pro file, add

    # From http://stackoverflow.com/a/37561981
    defineReplace(copyToDir) {
        files = $$1
        DIR = $$2
        LINK =
    
        for(FILE, files) {
            LINK += $$QMAKE_COPY $$shell_path($$FILE) $$shell_path($$DIR) $$escape_expand(\\n\\t)
        }
        return($$LINK)
    }
    
    defineReplace(copyToBuilddir) {
        return($$copyToDir($$1, $$OUT_PWD))
    }
    
    # Copy the binary files dependent on the system architecture
    win32 {
        message("Windows")
        QMAKE_POST_LINK += $$copyToBuilddir($$PWD/rclone/windows/rclone.exe)
    }else: unix:!macx {
        message("Linux")
        QMAKE_POST_LINK += $$copyToBuilddir($$PWD/rclone/linux/rclone)
    }else: macx: {
        # Here we want to place the binaries inside the application bundle, so the 
        # QMAKE_POST_LINK approach will not work because it places them in the same
        # directory as the bundle and not inside it. Instead, use QMAKE_BUNDLE_DATA.
        message("macOS")
        MediaFiles.files += $$PWD/rclone/macOS/rclone
        MediaFiles.path = Contents/MacOS
        QMAKE_BUNDLE_DATA += MediaFiles
    }
    

    Notice how there are slight differences for each platform, but in general the approach is the same.

    qmake will copy this files to the destination directory, and they will be accessible by simply making the process call to the local relative directory.

    In the following code, I call the executable from QML, and it's going to be very similar in C++ as well:

    var rcloneCommand
    if (Qt.platform.os === "windows") {
        console.log("Windows")
        rcloneCommand = "rclone.exe"
    } else {
        console.log("OSX/Linux")
        rcloneCommand = "./rclone"
    }
    qProcess.start(rcloneCommand, ["--config", "rclone.conf", "-v", "copy", "--stats", "1s", source, destination]);
    
    0 讨论(0)
  • 2020-12-03 19:30

    I don't think resources would work. Processes are created by operating system, and resources are handled by application.

    One possible solution would be bundle additional executables somewhere in your application directory and execute them from that path.

    0 讨论(0)
提交回复
热议问题