react-native: 0.73 fails to build on iOS with use_frameworks! :static due to yoga header path issue

Old Version

0.72.7

New Version

0.73.0

Description

As seems to happen with every new version, header paths are broken on iOS with use_frameworks! :static

pnpm install

pnpm expo start

eas build -p ios --profile development --local

fails to compile due to header paths issue

[RUN_FASTLANE] › Compiling .pnpm Pods/Yoga » PixelGrid.cpp
[RUN_FASTLANE]
❌  (node_modules/.pnpm/react-native@0.73.0_@babel+core@7.23.6_@babel+preset-env@7.23.6_react@18.2.0/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp:10:10)

   8 | #include <yoga/Yoga.h>
   9 |
> 10 | #include <yoga/algorithm/PixelGrid.h>
     |          ^ 'yoga/algorithm/PixelGrid.h' file not found
  11 | #include <yoga/numeric/Comparison.h>
  12 |
  13 | namespace facebook::yoga {

Steps to reproduce

https://github.com/evelant/expo50upgrade/

git clone https://github.com/evelant/expo50upgrade/

cd expo50upgrade

pnpm install

pnpm expo start

eas build -p ios --profile development --local

Affected Platforms

Build - MacOS

Output of npx react-native info

System:
  OS: macOS 14.2
  CPU: (10) arm64 Apple M1 Pro
  Memory: 348.45 MB / 16.00 GB
  Shell:
    version: 0.85.0
    path: /etc/profiles/per-user/imagio/bin/nu
Binaries:
  Node:
    version: 20.8.0
    path: /etc/profiles/per-user/imagio/bin/node
  Yarn:
    version: 1.22.21
    path: /etc/profiles/per-user/imagio/bin/yarn
  npm:
    version: 10.1.0
    path: /etc/profiles/per-user/imagio/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.12.1
    path: /etc/profiles/per-user/imagio/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.2
      - iOS 17.2
      - macOS 14.2
      - tvOS 17.2
      - watchOS 10.2
  Android SDK:
    API Levels:
      - "33"
    Build Tools:
      - 33.0.0
    Android NDK: Not Found
IDEs:
  Android Studio: Not Found
  Xcode:
    version: 15.1/15C65
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.8.1
    path: /etc/profiles/per-user/imagio/bin/javac
  Ruby:
    version: 3.1.4
    path: /etc/profiles/per-user/imagio/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.73.0
    wanted: 0.73.0
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

Stacktrace or Logs

[RUN_FASTLANE] › Compiling .pnpm Pods/Yoga » PixelGrid.cpp
[RUN_FASTLANE]
❌  (node_modules/.pnpm/react-native@0.73.0_@babel+core@7.23.6_@babel+preset-env@7.23.6_react@18.2.0/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp:10:10)

   8 | #include <yoga/Yoga.h>
   9 |
> 10 | #include <yoga/algorithm/PixelGrid.h>
     |          ^ 'yoga/algorithm/PixelGrid.h' file not found
  11 | #include <yoga/numeric/Comparison.h>
  12 |
  13 | namespace facebook::yoga {

Reproducer

https://github.com/evelant/expo50upgrade/

Screenshots and Videos

N/A

About this issue

  • Original URL
  • State: closed
  • Created 7 months ago
  • Reactions: 3
  • Comments: 39 (22 by maintainers)

Most upvoted comments

Banged my head against this for a couple of days - it seems that if I update the :path => to point to the monorepo root folder everything builds fine. For reference this is in an NX monorepo using React Native 0.73.2

  use_react_native!(
    :path => "../../#{config[:reactNativePath]}"
.... remaining settings ....
)

Not had chance to review the full functionality of our app yet, but the build is successful and at first glance everything seems to work.

Created PR for the release crew and the issue for the cherry pick. 0.74 should pick the fix in the next RC happening this Monday. I don’t have a timeline for 0.73.

Finally I managed this issue. In GemFile, modify cocoapods gem like following:

gem 'cocoapods', git: 'https://github.com/zep-us/CocoaPods', branch: 'header-mappings-dir-symlink-fix'

I patched cocoapods to make it work correctly when header_mappings_dir is set to symlinked dir.

Then run bundle install, and then run bundle exec pod install in ios directory. After that, build should work.

The problem is that use_frameworks changes how the files are arranged in the disk after pod install run. Frameworks must follow a very specific structure:

FrameworkName
'-> Headers
    '-> headerA.h
    '-> headerB.h
'-> ImplementationA.m
'-> PrivateHeaderC.h

While static libraries doesn’t.

On top of that, Monorepos usually moves the whole frameworks in a different location and uses symlinks to connect the expected position on disk to the monorepo location.

Those links get broken in our current setup. The specific details of what get broken depend on the monorepo that is used, but what I saw happening is that, with use frameworks, not all the symlink are set up correctly and that broke it.

@cipolleschi tested, it solves the problem for me 🎉 please, merge it into next releases 🙏

We recently committed some changes that should fix archiving of Yoga, here. Could you try to add these changes to node_modules/react_native/ReactCommon/yoga/yoga.podspec and see if it works?

The commit has not been released in any version as of today, If that works for you, we might want to cherry pick it in all the supported versions.

For me, it worked when I tried with pod version 1.14.3. The issue is with Subpath of the node for pod In symlinking I dont know but somehow with this version the linking of private headers points to $(PRIVATE_HEADERS_FOLDER_PATH)/node. Previously i was using pod 1.15.0 and headers were pointing to the linkage destinations.

@joaoveronezi I might be missing something, but for me changing the .podspec.json makes no difference — if I just do it, the Archive still fails, if I run pod update after doing it — the file is reset to its initial form. I only could pass the Archive if I go around all Yoga source and replace all include paths by relative ones… which works, but is very tedious.

@Slapbox symlink is stable for Metro, but not for the whole framework. My colleague that worked on simlinks for metro is now tackling monorepo scenarios, so, hopeful, we are going to have them working soon.

I solved my issue by going into the podspec.json and fixing the paths

Getting this issue in an Nx monorepo

Related: https://github.com/nrwl/nx/issues/20115

Same issue here.

I see it’s mentioned that monorepos aren’t officially supported, but also I saw this comment which says symlinks are stable in 0.73. What other challenges remain for monorepos? I sort of expected the support for symlinks to remedy this problem.

Monorepo setup are not officially supported, unfortunately. We haven’t figured out a proper way to handle them. In monorepo setup the problems are likely to be the various relative path we have in the podspecs. In the Yoga.podspec we have a few of them. Monorepo setups put those files in different paths w.r.t. the standard setup, and the podspecs layout is not handling that case.

Any way we can get around this? why use_frameworks! :linkage => :static is causing this to monorepo setup? as I understand from the thread it works without it?

I too am experiencing this with nx as my monorepo setup, with yarn. Started as soon as I added use_frameworks! :linkage => :static to my podfile (required by firebase).

Using the bare RN flow and latest version (0.73.1)

image

Hi @evelant thanks for the report. There are at least two things that concern me:

  1. pnpm is not officially supported yet, we know that there are issues with that setup
  2. you are using expo
  3. Dynamic frameworks jobs passed on 0.73. So we are confident that static frameworks will works as well, because dyn frameworks have stricter requirements.
npx react-native@latest init StaticFrameworks --version latest --skip-install
cd StaticFrameworks
yarn install
cd ios
bundle install
USE_FRAMEWORKS=static NO_FLIPPER=1 bundle exec pod install
open StaticFrameworks.xcworkspace

and then <kbd>⌘</kbd>+<kbd>B</kbd>, it works properly.