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

不问归期 提交于 2019-11-27 15:13:13

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.

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]);

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.

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 ?

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!