Skip to content

Building for iOS errors and some solutions #1250

Open
@gambhiro

Description

@gambhiro

Thanks for the cool project! I started to port an app to CXX-Qt so that I can build it for Android and iOS.

After setting up XCode and Qt Creator, I successfully compiled a "Hello World" app on a MacOS machine and deployed it to an iPad.

(This tutorial was helpful: How to develop a simple Qt app for iPad?)

Qt is installed to ~/Qt/ using their official open source online installer.

At this point my project is very similar to the qml_minimal example.

When trying to build it for iOS, a few errors I was able to solve:

Error: building for 'iOS', but linking in object file ... built for 'macOS'

Have to set the correct Rust target and qmake path in CMakeLists.txt:

if (IOS)
    set(Rust_CARGO_TARGET aarch64-apple-ios)
    set(qmake_path "$ENV{HOME}/Qt/6.8.3/ios/bin/qmake6")
endif()

cxx_qt_import_crate(
    MANIFEST_PATH rust/Cargo.toml
    CRATES simsapa_lib
    LOCKED
    QMAKE ${qmake_path}

    QT_MODULES ...
)

Error: linking with cc failed

error: linking with `cc` failed: exit status: 1
...
  = note: ld: library not found for -lSystem
          clang: error: linker command failed with exit code 1 (use -v to see invocation)

The solution was in this article: Brain Detour - Rust and macOS compilation / linking issue

Have to add this to ~/.zshrc:

export PATH=$PATH:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
export LIBRARY_PATH=$LIBRARY_PATH:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib

Error: Could not open ios ... QtCore.prl file to read libraries to link

In the Qt ios framework folders, the .prl files are under Versions/A/Resources.

I changed that path in qt-build-utils/src/lib.rs directly, but I think it should test somehow when building for ios.

diff --git a/crates/qt-build-utils/src/lib.rs b/crates/qt-build-utils/src/lib.rs
index 7f3a3900..be38cf2b 100644
--- a/crates/qt-build-utils/src/lib.rs
+++ b/crates/qt-build-utils/src/lib.rs
@@ -527,7 +527,7 @@ impl QtBuild {
             let (link_lib, prl_path) = if framework {
                 (
                     format!("framework=Qt{qt_module}"),
-                    format!("{lib_path}/Qt{qt_module}.framework/Resources/Qt{qt_module}.prl"),
+                    format!("{lib_path}/Qt{qt_module}.framework/Versions/A/Resources/Qt{qt_module}.prl"),
                 )
             } else {
                 (

Error: ... QtGui.framework/QtGui found in .prl file for Qt6Gui, but could not extract library base name to pass to linker command line

The .prl contained no form of the library with .a or other suffix, e.g.:

cat QtWidgets.framework/Versions/A/Resources/QtWidgets.prl
...
$$[QT_INSTALL_LIBS]/QtWidgets.framework/QtWidgets
...

You can see in this commit that in parse_cflags.rs I changed it to return the name without the suffix.

It seems to be a quick hack but I don't know how to make it more sophisticated for the correct context.

Error: include/cxx-qt/connection.h:9:10: fatal error: 'QtCore/QObject' file not found

warning: [email protected]: In file included from src/connection.cpp:7:
warning: [email protected]: /Users/sumedharama/prods/simsapa-ng-project/simsapa-ng/build/Qt_6_8_3_for_iOS/Debug/cargo/build/aarch64-apple-ios/debug/build/cxx-qt-76d4b2d0e25e8372/out/cxx-qt-build/target/crates/cxx-qt/include/cxx-qt/connection.h:9:10: fatal error: 'QtCore/QObject' file not found
warning: [email protected]:     9 | #include <QtCore/QObject>
warning: [email protected]:       |          ^~~~~~~~~~~~~~~~

...

warning: [email protected]: In file included from /Users/sumedharama/Qt/6.8.3/ios/lib/QtCore.framework/Headers/QtGlobal:1:
warning: [email protected]: /Users/sumedharama/Qt/6.8.3/ios/lib/QtCore.framework/Headers/qglobal.h:24:10: fatal error: 'QtCore/qtversionchecks.h' file not found
warning: [email protected]:    24 | #include <QtCore/qtversionchecks.h>
warning: [email protected]:       |          ^~~~~~~~~~~~~~~~~~~~~~~~~~

Update:

It turns out that the cc-rs builder.flag_if_supported() didn't include the -F framework paths on iOS. Changing it to builder.flag() solved this error.

for framework_path in self.framework_paths() {
    // NOTE: builder.flag_if_supported() doesn't work when building for iOS.
    builder.flag(format!("-F{}", framework_path.display()));
    // Also set the -rpath otherwise frameworks can not be found at runtime
    println!(
        "cargo::rustc-link-arg=-Wl,-rpath,{}",
        framework_path.display()
    );
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions