Opened 3 years ago

Closed 3 years ago

#62548 closed defect (fixed)

icu +universal does not work on Big Sur x86_64

Reported by: CharlesJS Owned by: kencu (Ken)
Priority: Normal Milestone:
Component: ports Version:
Keywords: Cc:
Port: icu

Description (last modified by jmroot (Joshua Root))

Many ports depend on the icu port. Unfortunately, its universal build does not work.

When trying to build a dependent port:

$ sudo port install gnutls +universal  
Warning: The macOS 11.2 SDK does not appear to be installed. Ports may not build correctly.
Warning: You can install it as part of the Xcode Command Line Tools package by running `xcode-select --install'.
--->  Computing dependencies for gnutls
Error: Cannot install libxslt for the archs 'arm64 x86_64' because
Error: its dependency icu cannot build for the required archs.
Error: Follow https://guide.macports.org/#project.tickets to report a bug.
Error: Processing of port gnutls failed

But:

$ port variants icu
icu has the variants:
   universal: Build for multiple architectures

And yet:

$ sudo port install icu +universal
--->  Fetching archive for icu
--->  Attempting to fetch icu-67.1_3.darwin_20.x86_64.tbz2 from https://pek.cn.packages.macports.org/macports/packages/icu
--->  Attempting to fetch icu-67.1_3.darwin_20.x86_64.tbz2.rmd160 from https://pek.cn.packages.macports.org/macports/packages/icu
--->  Installing icu @67.1_3
--->  Activating icu @67.1_3
--->  Cleaning icu
--->  Updating database of binaries
--->  Scanning binaries for linking errors
--->  No broken files found.
--->  No broken ports found.

$ file /opt/local/lib/libicudata.dylib
/opt/local/lib/libicudata.dylib: Mach-O 64-bit dynamically linked shared library x86_64

Change History (6)

comment:1 Changed 3 years ago by kencu (Ken)

I won't go into any great detail in this ticket about this issue, but you can try this one, if you feel so inclined:

<https://github.com/kencu/myports/tree/master/devel/icu>

I upgraded it to 68.2 but you can downgrade it back to 67.1 if you prefer.

% port -v installed icu
The following ports are currently installed:
  icu @68.2_0+universal (active) platform='darwin 20' archs='arm64 x86_64' date='2021-03-24T15:49:28-0700'
% file /opt/local/lib/libicudata.dylib
/opt/local/lib/libicudata.dylib: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] [arm64]
/opt/local/lib/libicudata.dylib (for architecture x86_64):	Mach-O 64-bit dynamically linked shared library x86_64
/opt/local/lib/libicudata.dylib (for architecture arm64):	Mach-O 64-bit dynamically linked shared library arm64
Last edited 3 years ago by kencu (Ken) (previous) (diff)

comment:2 Changed 3 years ago by jmroot (Joshua Root)

Description: modified (diff)
Port: icu added
Summary: Universal variant for icu, which many ports depend on, doesn't workicu +universal does not work on Big Sur x86_64

The technical details are that icu apparently needs to run executables that are built during the build process, and also can't be built with multiple -arch flags at once, but needs to build each arch separately and lipo them together. This means that it can be built +universal on Big Sur on arm64 hardware but not on x86_64.

comment:3 Changed 3 years ago by jmroot (Joshua Root)

If someone wants to work on making proper cross-compilation support work, the first step is to comment out the merger_must_run_binaries yes on line 207 of the Portfile. Then see what breaks and go from there. Even better would be to remove muniversal and get single-step universal building working, but that may be a much bigger undertaking.

comment:4 in reply to:  3 Changed 3 years ago by kencu (Ken)

Replying to jmroot:

remove muniversal and get single-step universal building working, but that may be a much bigger undertaking.

It was straightforward, once I understood what was going on, to fix a multiarch build for 10.15+ -- 5 minutes, as above. It becomes a 5-line build, and it builds fine with multiple arch flags if the libraries are the same bit depth.

However, you need to build it twice and lipo together for 32bit + 64bit libraries. Using the muniversal PG just on older systems <10.14 would do it. The proper flag to force the library bit depth is --with-library-bits=64 or --with-library-bits=32.

And I would split icu58 off into it's own legacy port, to simplify things in the Portfile, and get rid of icu-lx as it has no dependents and upstream recommends harfbuzz anyway.

Last edited 3 years ago by kencu (Ken) (previous) (diff)

comment:5 Changed 3 years ago by kencu (Ken)

Owner: set to kencu
Status: newaccepted

comment:6 Changed 3 years ago by kencu (Ken)

Resolution: fixed
Status: acceptedclosed

In 65ae07502eb013acf3a2a57b790097c487f3edb0/macports-ports (master):

icu: fix universal build on Darwin20+

prior to 10.14, universal means different library bit depths or endianness,
so we had to build separately and lipo together using the muniversal PG

We can't easily use the muniversal PG on darwin20+ as during the build,
icu has to run binaries to generate data, and the Intel Mac cannot run the
arm64 binaries generated by the muniversal PortGroup.

However we don't need to use the muniversal PortGroup because the universal
build on Darwin20+ has the same library bit depth and endianness on both
Intel and arm64.

Therefore we can build universal in one pass using clang's ability to generate both archs at once.

closes: #62548

no revbump as

  1. this should change no files on disk already installed
  2. a new version of icu is coming shortly
Note: See TracTickets for help on using tickets.