CMake, Xcode, and Swift and Objective-C

We're using CMake here, so we can build on Windows, Linux, and macOS. So now I'm trying to convert from Xcode to CMake (which then generates an xcode project, whee).

The main problems I'm running into are figuring out which settings to do via CMakeLists.txt. That's mostly tiresome. But theres a new issue, and I don't know enough about CMake to figure it out: compiling my .swift file generates a ${PROJECT}-Swift.h file, which is used by the ObjC files. Which is great.

Except I don't know how to tell CMake about that. (And I haven't figured out what variable describes where Xcode puts it, but that's more of a tiresome issue than head-against-desk issue...)

Has anyone run into and hopefully figured this out?

Answered by kithrup in 700093022

I'm using

# What I *want* to do is have this copied somewhere.
# But I don't know how to tell XCode to do that.
set_target_properties(LibraryControl PROPERTIES
    XCODE_ATTRIBUTE_SWIFT_OBJC_INTERFACE_HEADER_NAME "LibraryControl-Swift.h"
    XCODE_ATTRIBUTE_DERIVED_FILE_DIR "${PROJECT_BINARY_DIR}"
    XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${PROJECT_SOURCE_DIR}/common/mac/LibraryControl-Bridging-Header.h"
)

and then set target_include_directories appropriately in the other CMakeLists.txt files.

Hi, did you manage to solve it. I also struggling with the same issue.

Accepted Answer

I'm using

# What I *want* to do is have this copied somewhere.
# But I don't know how to tell XCode to do that.
set_target_properties(LibraryControl PROPERTIES
    XCODE_ATTRIBUTE_SWIFT_OBJC_INTERFACE_HEADER_NAME "LibraryControl-Swift.h"
    XCODE_ATTRIBUTE_DERIVED_FILE_DIR "${PROJECT_BINARY_DIR}"
    XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${PROJECT_SOURCE_DIR}/common/mac/LibraryControl-Bridging-Header.h"
)

and then set target_include_directories appropriately in the other CMakeLists.txt files.

There is now a better solution as the solution suggested here does not work with other build systems other than XCode. I would recommend following or contributing to: https://github.com/apple/swift-cmake-examples/blob/main/3_bidirectional_cxx_interop/cmake/modules/AddSwift.cmake

There are some issues with the function but the general solution is to create a custom command and add a target to execute the command.

function(_swift_generate_cxx_header_target target module header)
  cmake_parse_arguments(ARG "" "" "SOURCES;SEARCH_PATHS;DEPENDS" ${ARGN})
  if(NOT ARG_SOURCES)
    message(FATAL_ERROR "No sources provided to 'swift_generate_cxx_header_target'")
  endif()

  if(ARG_SEARCH_PATHS)
    list(TRANSFORM ARG_SEARCH_PATHS PREPEND "-I")
  endif()

  if(APPLE)
    set(SDK_FLAGS "-sdk" "${CMAKE_OSX_SYSROOT}")
  elseif(WIN32)
    set(SDK_FLAGS "-sdk" "$ENV{SDKROOT}")
  endif()

  add_custom_command(
    OUTPUT
      "${header}"
    COMMAND
      ${CMAKE_Swift_COMPILER} -frontend -typecheck
      ${ARG_SEARCH_PATHS}
      ${ARG_SOURCES}
      ${SDK_FLAGS}
      -module-name "${module}"
      -cxx-interoperability-mode=default
      -emit-clang-header-path "${header}"
    DEPENDS
      ${ARG_DEPENDS}
    COMMENT
      "Generating '${header}'"
  )

  add_custom_target("${target}"
    DEPENDS
      "${header}"
  )
endfunction()
CMake, Xcode, and Swift and Objective-C
 
 
Q