当应用程序作为产品集合的一部分构建时出现错误“/usr/bin/ld:找不到库:无法识别文件格式”

Error "/usr/bin/ld: cannot find library: File format not recognized" when application is built as part of a collection of products

我有一个 QBS 项目,它是子项目的集合,包括静态库、共享库和 Qt GUI 应用程序。 Qt GUI 应用程序一直给我的问题是 linking 阶段失败,抛出几个“/usr/bin/ld: 找不到 {library}: 文件格式无法识别”错误项目链。不过,它不会对所有库执行此操作,包括具有与抛出此错误的库几乎相同的 .qbs 文件的库。

奇怪的是,如果我自己构建应用程序,也就是说我 运行 从应用程序的项目目录中而不是在顶层进行 qbs,它构建得很好(假设所有依赖库存在于它们的安装目录中)。我看到的主要区别是,在构建完整项目时,项目中所有产品的应用程序的 cpp.libraryPaths 都会被忽略,并且应用程序会尝试对构建目录中生成的 lib 文件进行 link,而在自己构建应用程序时,cpp.libraryPaths 会按预期使用,并且安装目录中的文件已成功 linked。

我不知道为什么可以 link 编辑安装目录中的 lib 文件,而构建目录中的文件会抛出错误。最初导致 linking 失败的原因是什么?此外,如何修复我的项目配置,以便我可以通过在顶层调用 qbs 来构建所有内容。我可能以错误的方式处理这个问题吗?

这是我用来开始构建的命令:

qbs qbs.installRoot:. release

问题的直观表示:

Poject         <-- calling qbs here throws errors at linking application
|- LibraryOne
|- LibraryTwo
|- Application <-- calling qbs here works if libraries already built

这里是相关 qbs 文件的非常简化的复制

-- SubOne.qbs and SubTwo --
// These are identical excluding the files

StaticLibrary {
    name: // "One" or "Two"
    files: [/*Files...*/]

    Depends { 
        name: "Qt"
        submodules: [/*core, etc...*/]
    }

    Depends { name: "cpp" }

    // cpp depends and properties   

    Group {
        fileTagsFilter: product.type
        qbs.installDir: "lib"
        qbs.install: true
    }
}

-- App.qbs --

QtGuiApplication {
    name: "App"
    files: [/*Files...*/]

    Depends { name: "One" } // I comment out these depends when building the Application on it's own
    Depends { name: "Two" }

    Depends { name: "cpp" }
    cpp.includePaths: ["../One/include","..Two/include"]
    cpp.libraryPaths: ["../lib"] // <-- Ignored during full project build
    cpp.staticLibraries: ["One","Two"]

    Group {
        fileTagsFilter: product.type
        qbs.installDir: "bin"
        qbs.install: true
    }
}

从不 运行 子目录中的 qbs。你应该 always 运行 它在顶级项目文件中。在您的根目录中,您应该有一个这样的文件:

// project.qbs
import qbs

Project {
    // order doesn't matter here
    references: [
        "LibraryOne/SubOne.qbs",
        "LibraryTwo/SubTwo.qbs",
        "Application/App.qbs"
    ]
}

其次,你不应该在你的应用程序中设置 cpp.libraryPathscpp.staticLibraries,因为你在你的应用程序中的 Depends 项目已经处理了这个(永远不要将它们注释掉)。

您的 cpp.includePaths 属性也不应该在应用程序中设置,相反,它们应该进入每个静态库中的 Export 项,如下所示:

StaticLibrary {
    ...
    Export {
        Depends { name: "cpp" }
        cpp.includePaths: [product.sourceDirectory + "/include"]
    }
    ...
}

然后 运行 qbs -f project.qbs 一切都应该正确构建。