Cross-compile for iOS and POSIX platforms

Hello everyone!

I am about to build a simple 2 file test c++ library and than use it as a Cocoa Pod. The library does some basic logging.

I am struggling to find the right resources to what and how should I approach this problem. I am confused whether I should build a framework or build always from source.

I would be really really grateful if you could give me some advice or some examples what should I check or read. Also this might be also helpful for others. My end goal would be to create a library for general utilities for applications. For example, I would like to use a thirdparty HTTP client in C++ and link it with CMake using FetchContent. I know there are libraries that cannot be built for iOS, but lets assume that I want to link such a library.

So the general idea would be to have a library that holds some public APIs that I can import in Swift, ObjC or Java. Those APIs are defined by me, something like ApplicationUtils.postRequest, but that uses under the hood some other C++ library that is being linked by CMake.

What I do:

  • Build the framework with the following command and it gives me the framework as expected:
cmake -B build -G Xcode -DCMAKE_TOOLCHAIN_FILE=./toolchain/ios.toolchain.cmake -DPLATFORM=SIMULATORARM64
cmake --build build --config Release
  • In an example application I install the pod by its path, but when building the application the module cannot be found in a Swift file.

The file structure looks like this:

build/
— MyFramework.framework
include/
— MyClass.hpp
— module.modulemap
src/
— MyClass.cpp
CMakeLists.txt
MyFramework.podspec

The CMake file looks like this:

CMAKE_MINIMUM_REQUIRED(VERSION 3.15)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

PROJECT(MyFramework)

set(SOURCES
  src/MyClass.cpp
)

set(HEADERS
  include/MyClass.hpp
  include/module.modulemap
)

add_library(MyFramework STATIC ${HEADERS} ${SOURCES})

target_include_directories(MyFramework
    PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}/include
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
)

set_target_properties(MyFramework PROPERTIES
  FRAMEWORK TRUE
  VERSION 1.0.0
  SOVERSION 1.0.0
  PUBLIC_HEADER "${HEADERS}"
  FRAMEWORK_VERSION A
  XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET 13.0
  XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym"
)

The podspec looks like this:

Pod::Spec.new do |s|
  s.name         = "MyFramework"
  s.version      = "1.0.0"
  s.summary      = "Core"
  s.homepage     = "Core"
  s.license      = "MIT"
  s.authors      = "Author"
  s.source       = { :git => 'https://example.com/MyFramework.git', :tag => s.version.to_s }

  s.platform     = :ios, '13.0'

  s.module_map = 'include/module.modulemap'

  s.vendored_frameworks = 'build/MyFramework.framework'
  s.public_header_files = 'build/MyFramework.framework/Headers/*'
  s.source_files = 'build/MyFramework.framework/Headers/*'

  s.libraries = 'c++'

end

Thank you in advance!