Search code examples
c++qtqt5qprocessqresource

Include adb with Qt application


I’m using Qt 5.3 on OS X. I have a program that depends on the android tool adb, so I’m trying to include it as a resource.

In my project file I have:

RESOURCES = app.qrc

In app.qrc I have:

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <file>assets/adb</file>
</qresource>

In my app:

QResource::registerResource("app.rcc");

// I've run with and w/o a compiled .rcc file. No difference.

QProcess *kill_adb=new QProcess;
    kill_adb->start("/assets/adb kill-server");
    kill_adb->waitForFinished(-1);
    int exitcode = kill_adb->exitCode();

    QString s = QString::number(exitcode);
    QMessageBox::critical(
     this,
     tr("exit code:"),
     s);
    delete kill_adb;

Calls to /assets/adb fail. If I use a path to a local adb the code works. How can I include adb with my program?


Solution

  • QProcess can only execute real files on your filesystem. You cannot execute a file if you do not have a file.

    Gnu/Linux, Windows, Android, Mac, etc can only execute files as they are filesystem based operating systems. QProcess obeys that and this is what it internally boils down to, on Linux at least:

    static inline int qt_safe_execve(const char *filename, char *const argv[],
                                     char *const envp[])
    {
        int ret;
        EINTR_LOOP(ret, ::execve(filename, argv, envp));
        return ret;
    }
    
    static inline int qt_safe_execv(const char *path, char *const argv[])
    {
        int ret;
        EINTR_LOOP(ret, ::execv(path, argv));
        return ret;
    }
    
    static inline int qt_safe_execvp(const char *file, char *const argv[])
    {
        int ret;
        EINTR_LOOP(ret, ::execvp(file, argv));
        return ret;
    }
    

    As you can see, it will call the different exec* variants which goes through the same system call then. They all require the file name.

    The only way to make it possible without proper installer given to the end user directly or indirectly, is to first read the content out and write that into a temporary file if you really wish to do this.

    That being said, I would personally go for a real installer setup.