How to detect target iOS architecture in qmake? - ios

I have a Qt Version that supports following ABI's (Qt Creator → Preferences → Build & Run / Qt Versions):
arm-macos-generic-mach_o-32bit
arm-macos-generic-mach_o-64bit
x86-macos-generic-mach_o-32bit
x86-macos-generic-mach_o-64bit
So, combining in a Qt Kit this Qt Version with different compilers I can build libs for all mentioned architectures.
At the same time the mkspecs/qconfig.pri contains:
host_build {
QT_ARCH = x86_64
QT_TARGET_ARCH = arm
} else {
QT_ARCH = arm
}
So, in a .pro file I can not detect a target architecture (it is always arm). I can check CONFIG for iphonesimulator value and so detect arm/not arm architecture but there is still 32bit/64bit issue.
Is there a way to distinguish armv7/arm64/... builds in qmake (.pro file)?

The only method I found is:
Qt Creator → Preferences → Build & Run / Kits → Environment → Change...
Than set specific IOS_ARCH env var for each kit.
In .pro file:
IOS_ARCH = $$(IOS_ARCH)
!isEmpty(IOS_ARCH): TARGET_ARCH = $$IOS_ARCH
# then use $$TARGET_ARCH as usual

Related

iOS swift app build fails with cyclic dependency error in Xcode 14+

I have a swift iOS app with two static libraries - lib1 and lib2 (say). Lib2 has a dependency on Lib1 (i.e it imports Lib1 to use its types). Lib1 and Lib2 are set as dependencies for the AppTarget (when built, results in the .app file).
I get the following cyclic dependency error when building Lib1. Similar error is observed when building the other targets.
SwiftDriverJobDiscovery normal x86_64 Compiling <FileName1>.swift (in target '<Lib1>' from project '<ProjectName>')
error: Cycle inside <Lib1>; building could produce unreliable results.
Cycle details:
→ Target '<Lib1>': Libtool /Users/<user-name>/<some-path>/<Lib1>.a normal
○ Target '<Lib1>' has Swift tasks not blocking downstream targets
○ Target '<Lib1>': SwiftGeneratePch normal x86_64 Compiling bridging header
○ Target '<Lib1>': SwiftCompile normal x86_64 Compiling <FileName2>.swift /Users/<user-name>/<some-path>/<Filename2>.swift
○ Target '<Lib1>': SwiftGeneratePch normal x86_64 Compiling bridging header
Raw dependency cycle trace:
target: ->
node: <all> ->
command: <all> ->
node: /Users/<user-name/<some-path>/<Lib1>.a -> command: P1:target-<Lib1>-6d14b29d8d3402955e18e7b7c2cd5bd8502d5dd7097f7536813aba73cac1c1d5-:Debug:Libtool /Users/<user-name>/<some-path>/<Lib1>.a normal ->
node: /Users/<user-name>/<some-path>/x86_64/<FileName3>-8014457a59adc1f8a995a14873eb809b.o ->
command: P0:target-<Lib1>-6d14b29d8d3402955e18e7b7c2cd5bd8502d5dd7097f7536813aba73cac1c1d5-:Debug:SwiftDriver Compilation <Lib1> normal x86_64 com.apple.xcode.tools.swift.compiler ->
CYCLE POINT ->
customTask: <SwiftDriverJob identifier=-4908891831242875468 arch=x86_64 variant=normal job=<PlannedSwiftDriverJob [target(7)]:GeneratePch <Lib1> dependencies=["target(8)", "target(9)", "target(10)"]> isUsingWholeModuleOptimization=false compilerPath=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc> ->
customTask: <SwiftDriverJob identifier=-4908891831242875468 arch=x86_64 variant=normal job=<PlannedSwiftDriverJob [target(8)]:Compile <Lib1> <FileName2>.swift dependencies=["target(7)"]> isUsingWholeModuleOptimization=false compilerPath=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc> ->
customTask: <SwiftDriverJob identifier=-4908891831242875468 arch=x86_64 variant=normal job=<PlannedSwiftDriverJob [target(7)]:GeneratePch <Lib1> dependencies=["target(8)", "target(9)", "target(10)"]> isUsingWholeModuleOptimization=false compilerPath=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc>
In the above error message, FileName1 and FileName2 are swift files that invoke C++ methods using an intermediate ObjC++ bridge layer. I have two files named FileName3 but different extensions - .swift and .mm. Since, FileName2 is referred as .o here, I think it is referring to FileName3.mm (i.e the ObjC++ file).
I have checked the code thoroughly for any form of cyclic dependency (like, two classes depending on each other - as mentioned in many stackoverflow posts), but it's all good. What's more, the same build worked on Xcode 13.x. After updating to Xcode 14.x, I'm getting this cyclic dependency error.
But in the last three lines of the error message, you can see a cyclic dependency.
First step: [Target(7)] Generate pch and depends on [target(8), target(9), target(10)]
Second step: [Target(8)] Compile FileName2.swift, depends on [target(7)]
Target(7) is dependent on target(8) and target(8) is dependent on target(7). What is target(7), target(8) etc? Where can I find out what kind of target it exactly is?
I use cmake to set the dependencies and generate the Xcode project.
What is this error? What am I missing here?
I've been stuck for days and any help would be greatly appreciated.
After so much time spent on searching, this is the answer.
Checkout ctietze's answer to this post in Apple forum
defaults write com.apple.dt.XCBuild EnableSwiftBuildSystemIntegration 0
After disabling the new build system, I'm not getting the cyclic dependency error anymore.

Unable to build the library using cargo lipo --release

Unable to build the library using cargo lipo --release
I am trying to make a cross-platform library using rust for ios target. I am following this article (Building and Deploying a Rust library on iOS).
*Note: I followed the same steps and my project structure also looks the same *
After completing the code and project setup the last step is to build the library. When I try to build the library using cargo lipo --release. It throws this error:
[ERROR cargo_lipo] No library target found for "my-project-name"
Also, note that I am only able to install support for two platforms. (aarch64-apple-ios and x86_64-apple-darwin). I think the reason is that they have dropped the support for 32-bit architectures.
So, when I run
rustup target add aarch64-apple-ios armv7-apple-ios armv7s-apple-ios x86_64-apple-ios i386-apple-ios.
It throws error: error: component 'rust-std' for target 'armv7-apple-ios' is unavailable for download for channel stable
Cargo.toml
[package]
name = "rustylib"
version = "0.1.0"
edition = "2018"
crate-type = ["staticlib", "cdylib"]
rustylib.rs
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
char *hello(const char *to);
void hello_release(char *s);
The rest of the project structure is the usual rust code.
The output of rustup show
Default host: x86_64-apple-darwin
rustup home: /Users/my-username/.rustup
installed toolchains
stable-x86_64-apple-darwin
nightly-x86_64-apple-darwin (default)
installed targets for active toolchain
aarch64-apple-ios
x86_64-apple-darwin
active toolchain
nightly-x86_64-apple-darwin (default)
rustc 1.52.0-nightly (acca81892 2021-03-13)
OS & Rust
Rust: rustc 1.50.0 (cb75ad5db 2021-02-10)
OS: macOS Bug Sur (11.2.3)
Xcode & Command line tools: 12.4
Your Cargo.toml is wrong.
If you look into the guide you linked in your question, you can see, that the crate-type has to be below the [lib] tag like so:
[package]
name = "greetings"
version = "0.1.1"
authors = ["fluffyemily <fluffyemily#mozilla.com>"]
description = "Example static library project built for iOS"
publish = false
[lib]
name = "greetings"
crate-type = ["staticlib", "cdylib"]
Also your code has to be in cargo/src/lib.rs by default as stated in the document (and not in rustylib.rs).
You can run cargo new rustylib --lib from the command line to create all the boilerplate, so that you only have to add the dependencies and the crate-type in the [lib] section of your Cargo.toml.
Edit
I think there is another problem:
You have entered C code in your rustylib.rs file, which can not work. I think what you intended to do, was to create the C bridge, which is called cargo/src/greetings.h in the guide you linked.

conan error:I need to cross build packages for os:iOS with my Macos, but when the first package was done, it broke my cpt while testing

I want to use cpt to cross build several iOS packages with the arch "armv7", "armv8", "x86_64" and the build_type "Debug", "Release". But when the first package was testing, it broke my building with that "/bin/sh: bin/test_package: Bad CPU type in executable". I know I cannot run armv7 on my x86_64 host arch, but I do not want my building plan failed. How can I continue my building without testing the package or successfully testing my package.
I have checked my CMakeLists.txt and conanfile.py in my dir test_package, but I did not know how to fix that problem.
Here is part of the conanfile.py in test_package
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def test(self):
with tools.environment_append(RunEnvironment(self).vars):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)
Here is my CMakeLists.txt in test_package
project(test_package)
cmake_minimum_required(VERSION 2.8.11)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
add_executable(${PROJECT_NAME} test_package.cpp)
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
Here is part of my build.py
builder = ConanMultiPackager()
# add builder settings with the arch and type of build
def add_builder_settings(arch, build_type):
requires = {"*": ["darwin-toolchain/1.0.4#theodelrieu/testing"]}
options = {"darwin-toolchain:bitcode": False}
builder.add(settings={"os": "iOS", "arch": arch, "build_type": build_type, "os.version": "10.0", "compiler": "apple-clang"},
build_requires=requires, options=options)
# add build settings for iOS
add_builder_settings("armv7", "Debug")
add_builder_settings("armv7", "Release")
add_builder_settings("armv8", "Debug")
add_builder_settings("armv8", "Release")
add_builder_settings("x86_64", "Debug")
add_builder_settings("x86_64", "Release")
Here is my error report
libx264/20171211#username/stable (test package): Running test()
/bin/sh: bin/test_package: Bad CPU type in executable
I want to build 6 types of packages with one build.py. But it failed with building only one package.
To avoid test_package execution when cross-building, I strongly recommend the Bincrafters idea:
from conans import ConanFile, CMake, tools
import os
class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def test(self):
if not tools.cross_building(self.settings):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)
The idea here is skipping the execution and Conan detects that arch != build_arch.
You can take a look the in original code here:
https://github.com/bincrafters/templates/blob/master/default/test_package/conanfile.py#L15

Import Kotlin/Native framework in Cocoapod

I'm trying to add a vendored framework built with Kotlin/Native in a private CocoaPod but I get an error:
I have generated an iOS framework with Kotlin/Native.
I copy the framework folder (compiled/generated by Konan) into my custom pod folder
In the podspec, I add the framework path in the "vendored_frameworks" list
I launch pod repo push myCocoapodsRepo myProject.podspec --verbose"
I receive an error :
[iOS] xcodebuild: fatal error: lipo: input file (/Users/jeandaube/Library/Developer/Xcode/DerivedData/App-auugdpsmbbpvarfzghxatkvwftsn/Build/Products/Release-iphonesimulator/App.app/Frameworks/MyProject.framework/MyProject) must be a fat file when the -remove option is specified
Should I somehow change the format of how I export the framework with Konan in a first place?
You're getting the error because, by default, Kotlin Native only produces binaries for a single architecture. CocoaPods than fails when it tries to treat it as a "fat" binary with multiple architectures. Since you'll need multiple architectures anyway (at least arm64 for the device and x86_64 for the simulator) the approach I'm using is to create both architectures and then merge them with lipo The resultant fat framework can then be vended by CocoaPods or just drag/drop installed in Xcode.
def outputDirectory = "$export_dir/$projectName/$projectVersion"
def outputFramework = "$outputDirectory/${projectName}.framework"
konanArtifacts {
// Declare building into a framework, build arm64 for device, x64 for simulator
framework(projectName, targets: ['ios_arm64', 'ios_x64' ]) {
// The multiplatform support is disabled by default.
enableMultiplatform true
}
}
// combine original arm64 and x64 libraries into a single library in
// the exported framework folder
task combineArchitectures(type: Exec, dependsOn: compileKonanLibrary) {
executable 'lipo'
args = [
'-create',
'-arch',
'arm64',
new File(compileKonanLibraryIos_arm64.artifact, 'Library'),
'-arch',
'x86_64',
new File(compileKonanLibraryIos_x64.artifact, 'Library'),
'-output',
"$outputFramework/Library"
]
}
// export the arm64 (doesn't matter which really) framework, skipping
// the library binary itself
task exportFramework(type: Copy, dependsOn: compileKonanLibrary) {
from compileKonanLibraryIos_arm64.artifact
into outputFramework
exclude projectName
finalizedBy combineArchitectures
}
// build a pod spec by copying and updating a template file
task exportPodspec(type: Copy) {
from "Library.podspec"
into outputDirectory
filter {
it.replaceAll('##projectName##', projectName)
.replaceAll('##projectVersion##', projectVersion)
}
}
task export {
dependsOn "exportFramework"
dependsOn "exportPodspec"
}
Kotlin/Native does not produce multiarchitecture (aka fat) binaries (see https://en.wikipedia.org/wiki/Fat_binary) thus an attempt to run lipo on the framework it produces does not make sense.

yocto SDK krogoth cmake FindBoost not found

I am trying to find the boost libraries (cmake) inside the Yocto SDK with extended environment on krogoth.
The default cmake Find_
find_package(Boost REQUIRED)
The standard error message
Unable to find the requested Boost libraries.
Unable to find the Boost header files. Please set BOOST_ROOT to the root
directory containing Boost or BOOST_INCLUDEDIR to the directory containing
Boost's headers.
Call Stack (most recent call first):
CMakeLists.txt:3 (find_package)
The following is a snippet from my conf/local.conf
IMAGE_INSTALL_append = " boost-dev"
IMAGE_INSTALL_append = " boost"
IMAGE_INSTALL_append = " kernel-devsrc"
MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS += "kernel-module-hello"
KERNEL_MODULE_AUTO_lOAD += "hello-md"
LCHAIN_HOST_TASK_append = "${SDK_EXTRA_TOOLS}"
SDK_EXTRA_TOOLS = " nativesdk-cmake
I am using the native cmake
auke#xenialxerus:~/workspace/beaglebone-dev/build$ which cmake
/home/auke/workspace/beaglebone-dev/poky-sdk/tmp/sysroots/x86_64-linux/usr/bin/
since I:
source environment-setup-cortexa8hf-neon-poky-linux-gnueabi
looking for the usual headers in:
find ./tmp/sysroots/beaglebone/usr/include/boost/
..
/tmp/sysroots/beaglebone/usr/include/boost/vmd/list/to_seq.hpp
./tmp/sysroots/beaglebone/usr/include/boost/vmd/list/to_tuple.hpp
./tmp/sysroots/beaglebone/usr/include/boost/vmd/to_list.hpp
./tmp/sysroots/beaglebone/usr/include/boost/vmd/empty.hpp
./tmp/sysroots/beaglebone/usr/include/boost/vmd/is_list.hpp
./tmp/sysroots/beaglebone/usr/include/boost/vmd/size.hpp
./tmp/sysroots/beaglebone/usr/include/boost/vmd/get_type.hpp
./tmp/sysroots/beaglebone/usr/include/boost/vmd/assert_is_identifier.hpp
./tmp/sysroots/beaglebone/usr/include/boost/vmd/is_number.hpp
..
just like the binaries:
./tmp/sysroots/beaglebone/usr/lib/libboost_system-mt.a
./tmp/sysroots/beaglebone/usr/lib/libboost_iostreams.so.1.60.0
./tmp/sysroots/beaglebone/usr/lib/libboost_serialization-mt.a
./tmp/sysroots/beaglebone/usr/lib/libboost_date_time-mt.a
./tmp/sysroots/beaglebone/usr/lib/libboost_date_time.a
./tmp/sysroots/beaglebone/usr/lib/libboost_thread.so
./tmp/sysroots/beaglebone/usr/lib/libboost_signals-mt.a
./tmp/sysroots/beaglebone/usr/lib/libboost_date_time-mt.so
./tmp/sysroots/beaglebone/usr/lib/libboost_graph-mt.a
./tmp/sysroots/beaglebone/usr/lib/libboost_iostreams.so
./tmp/sysroots/beaglebone/usr/lib/libboost_regex.so
./tmp/sysroots/beaglebone/usr/lib/libboost_wserialization.so.1
Is there something that i might have overlooked?
regards Auke
You should use
bitbake -c populate_sdk <image_name> to generate the SDK based on your image;
As an alternative to locating and downloading a toolchain installer,
you can build the toolchain installer one of two ways if you have a
Build Directory:
*Use bitbake meta-toolchain. This method requires you to still install
the target sysroot by installing and extracting it separately. For
information on how to install the sysroot, see the "Extracting the
Root Filesystem" section.
*Use bitbake -c populate_sdk. This method has significant
advantages over the previous method because it results in a toolchain
installer that contains the sysroot that matches your target root
filesystem.
Also, using the variable TOOLCHAIN_HOST_TASK to add more packages.
http://www.yoctoproject.org/docs/1.8/ref-manual/ref-manual.html
This variable lists packages the OpenEmbedded build system uses when
building an SDK, which contains a cross-development environment. The
packages specified by this variable are part of the toolchain set that
runs on the SDKMACHINE, and each package should usually have the
prefix "nativesdk-". When building an SDK using bitbake -c
populate_sdk , a default list of packages is set in this
variable, but you can add additional packages to the list.
e.g.
TOOLCHAIN_HOST_TASK += “nativesdk-libqt5core-dev”

Resources