Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unknown type name 'namespace' in umbrella-header.h that include cpp headers #12105

Open
Alexufo opened this issue Oct 22, 2023 · 4 comments
Open

Comments

@Alexufo
Copy link

Alexufo commented Oct 22, 2023

I am trying to compile a swift project with my pod. My pod contains binary libs and c++ wrapper for them.
I have successfully created the pod for the default objc project and everything works fine.

Then I try to integrate my pod into the default swift project in the same way and I get

image

I remove "import myModule" from swift (the project starts compiling without errors) and put bridge-header.h. After that I can access my pod, but I don't want to use bridge-header.h Is it possible?

@ospfranco
Copy link

Did you find a solution for this?

@Alexufo
Copy link
Author

Alexufo commented Nov 23, 2023

Did you find a solution for this?

No. I use bridge-header in parent project. A bit hacky.

 s.xcconfig = { "SWIFT_OBJC_BRIDGING_HEADER" => "${PODS_CONFIGURATION_BUILD_DIR}/Name/Name.framework/Headers/Name-Bridging-Header.h"}

Bridge header will be avalable in xcode after first build.

@ospfranco
Copy link

ospfranco commented Nov 23, 2023

The root issue is Swift compiler fault, it doesn't support C++. Whenever you have Swift files together with C++ files, it's the Swift compiler that will kick-in and will try to compile the headers as C headers independently of what you tell it, file extensions, etc. Here is the workaround I found:

require "json"

package = JSON.parse(File.read(File.join(__dir__, "package.json")))

Pod::Spec.new do |s|
  s.name           = "matrix"
  s.version        = package["version"]
  s.summary        = package["description"]
  s.homepage       = package["homepage"]
  s.license        = package["license"]
  s.authors        = package["author"]
  s.platforms      = { :ios => "13.0" }

  s.pod_target_xcconfig = {
    "DEFINES_MODULE" => "YES",
    "SWIFT_COMPILATION_MODE" => "wholemodule",
    "CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
    "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/cpp/\"/** " # This will link the headers at compile time, flag passed directly to the compiler
  }

  s.source_files = "ios/**/*.{mm,swift}", "cpp/**/*.{cpp,c}" # Do not include the headers in the sources, then XCode won't try to compile them

  s.preserve_paths = [
    "cpp/**/*.h",
    "ios/**/*.h"
  ]
  
  s.dependency "React"
  s.dependency "React-Core"
  s.dependency "React-callinvoker"
end

By not including the headers in source_files XCode does not try to compile them, but by adding them to the HEADER_SEARCH_PATHS they are still found on the linking step of the compilation.

One side effect is that the headers will not appear on the project explorer view on XCode which is annoying if you are developing something from scratch but I don't see any other workaround.

The other alternative would be as stated in the Stack Overflow answer, to hide everything with macros that check if C++ is compiling the header.

It does not solve the problem the generated umbrella header does not check for this, which CocoaPods can better handle.

@Alexufo
Copy link
Author

Alexufo commented Dec 6, 2023

Thanks. I left PODS_CONFIGURATION_BUILD_DIR.

My working pod is

Pod::Spec.new do |s|
  s.name             = 'Id'
  s.version          = '0.1.0'
  s.summary          = 'Swift pod'
  s.homepage         = 'https://'

  s.source           = { :path => './' }
  
  s.ios.deployment_target = '11.0'
  s.frameworks = 'UIKit', 'Foundation','AVFoundation' , 'CoreVideo', 'CoreGraphics', 'CoreMedia'
  
  s.ios.resources = 'Core/data'
  s.ios.vendored_frameworks = 'Core/lib/*.xcframework'
  
  s.xcconfig = {
    'SWIFT_OBJC_BRIDGING_HEADER' => '$(PODS_ROOT)/../S/S-Bridging-Header.h',
    'HEADER_SEARCH_PATHS' =>
    '$(PODS_ROOT)/../Core/wrap/objcs/include ' +
    '$(PODS_ROOT)/../Core/wrap/objcs/include_impl ' +
    '$(PODS_ROOT)/../Core/wrap/objci/include ' +
    '$(PODS_ROOT)/../Core/wrap/objci/include_impl ' +
    '$(PODS_ROOT)/../Core/include'
  }

  s.pod_target_xcconfig = {  
    "DEFINES_MODULE" => "YES",
    'ENABLE_BITCODE' => "NO",
    'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386'
  }
  
  s.subspec 'Core' do |h|
    h.source_files =  "Core/wrap/**/*.{mm,h}", "Core/include/**/*.{mm,h}"
    h.header_mappings_dir = './'
  end
  
  s.subspec 'S' do |w|
    w.source_files =  "S/**/*.{mm,h}"
  end
  
end

preserve_paths doesn't work for me. If I ignore the *.h, they won't be copied to the build folder. If I move xcconfig to pod_target_xcconfig, I get the problem I wrote about earlier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants