Compile boost como biblioteca universal (arquiteturas Intel e Apple Silicon)

Oct 27 2020

Estou tentando construir uma biblioteca boost como dylib no MacOS. Eu preciso construí-lo para a arquitetura Intel e para a próxima arquitetura Apple Silicon (arm64).

Baixei boost e executei os seguintes comandos:

./bootstrap.sh
./b2 -address-model=64 architecture=combined -a

lipo -archssempre mostra arquitetura dylibs produzida é x86_64.

Eu tenho Xcode12 beta e MacOS Catalina 10.15.7,

Posso construir uma biblioteca universal de amostra se criar um projeto no Xcode e definir archs arm64 x86_64nas configurações de construção.

A execução do comando ./b2 cxxflags="-arch arm64 -arch x86_64"falha com os seguintes erros:

    "clang++" -x c++ -fvisibility-inlines-hidden -m64 -O3 -Wall -fvisibility=hidden -Wno-inline -arch arm64 -arch x86_64 -ftemplate-depth-255 -fvisibility=hidden -fvisibility-inlines-hidden -DBOOST_ALL_NO_LIB=1 -DNDEBUG -I"." -c -o "bin.v2/libs/serialization/build/clang-darwin-12.0/release/link-static/threading-multi/visibility-hidden/polymorphic_xml_iarchive.o" "libs/serialization/src/polymorphic_xml_iarchive.cpp"

...failed clang-darwin.compile.c++ bin.v2/libs/serialization/build/clang-darwin-12.0/release/link-static/threading-multi/visibility-hidden/polymorphic_xml_iarchive.o...
clang-darwin.compile.c++ bin.v2/libs/serialization/build/clang-darwin-12.0/release/link-static/threading-multi/visibility-hidden/polymorphic_xml_oarchive.o
In file included from libs/serialization/src/polymorphic_xml_oarchive.cpp:16:
In file included from ./boost/serialization/config.hpp:18:
In file included from ./boost/config.hpp:57:
In file included from ./boost/config/platform/macos.hpp:28:
In file included from ./boost/config/detail/posix_features.hpp:18:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/unistd.h:71:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/_types.h:27:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types.h:32:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/cdefs.h:807:2: error: Unsupported architecture
#error Unsupported architecture
 ^
In file included from libs/serialization/src/polymorphic_xml_oarchive.cpp:16:
In file included from ./boost/serialization/config.hpp:18:
In file included from ./boost/config.hpp:57:
In file included from ./boost/config/platform/macos.hpp:28:
In file included from ./boost/config/detail/posix_features.hpp:18:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/unistd.h:71:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/_types.h:27:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types.h:33:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/machine/_types.h:34:2: error: architecture not supported
#error architecture not supported
 ^
In file included from libs/serialization/src/polymorphic_xml_oarchive.cpp:16:
In file included from ./boost/serialization/config.hpp:18:
In file included from ./boost/config.hpp:57:
In file included from ./boost/config/platform/macos.hpp:28:
In file included from ./boost/config/detail/posix_features.hpp:18:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/unistd.h:71:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/_types.h:27:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types.h:55:9: error: unknown type name '__int64_t'
typedef __int64_t       __darwin_blkcnt_t;      /* total blocks */
        ^
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types.h:56:9: error: unknown type name '__int32_t'; did you mean '__int128_t'?
typedef __int32_t       __darwin_blksize_t;     /* preferred block size */
        ^
note: '__int128_t' declared here
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types.h:57:9: error: unknown type name '__int32_t'; did you mean '__int128_t'?
typedef __int32_t       __darwin_dev_t;         /* dev_t */
        ^
note: '__int128_t' declared here
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types.h:60:9: error: unknown type name '__uint32_t'; did you mean '__uint128_t'?
typedef __uint32_t      __darwin_gid_t;         /* [???] process and group IDs */
        ^
note: '__uint128_t' declared here
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types.h:61:9: error: unknown type name '__uint32_t'; did you mean '__uint128_t'?
typedef __uint32_t      __darwin_id_t;          /* [XSI] pid_t, uid_t, or gid_t*/
        ^

Respostas

1 NavanChauhan Nov 13 2020 at 23:38

Eu estava enfrentando o mesmo problema e me deparei com esta resposta , que era para criar binários universais para i386 e x86_64.

Para resumir a resposta, você precisa executar ./b2duas vezes (com conjuntos de ferramentas diferentes, já que o clang sempre cria para x86_64, mesmo se você passar nos CXXFlags apropriados

Este é o script que usei para primeiro gerar individualmente as bibliotecas necessárias e, em seguida, combinei-as usando lipo

#!/bin/sh

rm -rf arm64 x86_64 universal
./bootstrap.sh --with-toolset=clang --with-libraries=thread,system,filesystem,program_options,serialization 
./b2  cxxflags="-arch arm64" toolset=darwin -a
mkdir -p arm64 && cp stage/lib/*.dylib arm64
./b2 toolset=clang cxxflags="-arch arm64 -arch x86_64" -a
mkdir x86_64 && cp stage/lib/*.dylib x86_64
mkdir universal
for dylib in arm64/*; do 
  lipo -create -arch arm64 $dylib -arch x86_64 x86_64/$(basename $dylib) -output universal/$(basename $dylib); 
done
1 bfx Dec 08 2020 at 00:59

O seguinte funciona para mim em Big Sur usando o Xcode 12.2. Em Catalina 10.15.7 (19H15), recebo as mesmas mensagens de erro que OP.

./bootstrap.sh --with-libraries=regex,date_time 
./b2 architecture=combined cxxflags="-arch x86_64 -arch arm64"
lorcan Nov 14 2020 at 00:05

Você não precisa usar o lipo, você pode passar -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdkpara cxxflags e ele criará uma biblioteca universal pronta para uso.

PetrHadraba Jan 05 2021 at 00:13

Segui a resposta de Navan Chauhan, que parece ser o caminho a seguir no macOS 10.15.7 com Xcode 12.3.

Meu único problema era que o sistema de compilação estava adicionando a -arch armv4topção clang adicional (ou algo semelhante) que falha a compilação. Usar o architecture=combinenão pode funcionar tão bem, pois é capaz de gerenciar apenas Intel e PowerPC . O que funciona para mim em vez disso é:

  1. bootstrap.sh --with-toolset=clang-darwine cxxflags, cflagse linkflagsdefinido para -arch x86_64 -arch arm64mais opções adicionais.
  2. x86_64 build: b2 toolset=clang-darwin target-os=darwin architecture=x86 stageand cxxflags, cflagse linkflagsdefinido como -arch x86_64apenas (mais opções adicionais).
  3. arm64 build: b2 toolset=clang-darwin target-os=darwin architecture=arm abi=aapcs stageand cxxflags, cflagse linkflagsdefinido como -arch arm64apenas (mais opções adicionais).
  4. Mesclar bibliotecas com lipo...

Fui forçado a definir a ABI também porque a suposição automática de algo não é capaz de reconhecer o objetivo do Apple Silicon, pois algumas coisas de montagem não são compiladas - portanto, símbolos ausentes mais tarde durante a construção. Finalmente, o armv4tproblema é resolvido pelo clang-darwinconjunto de ferramentas.

A única ressalva disso no momento é que ambas as compilações vão para os mesmos diretórios de arquitetura / configuração que podem ser resolvidos por costume user-config.jamou por chamada imediata para installlogo após cada uma, stageque foi o que eu fiz.

Funciona em:

  • Plataforma host: Intel
  • macOS 10.15.7
  • Xcode 12.3 (com ferramentas de linha de comando instaladas)
  • Boost 1.75.0 (compressão dependente e bibliotecas ICU já compiladas como universais)