Cross-Compiling wxWidgets for Mac x86 and ARM64

285 views
Skip to first unread message

Henry M

unread,
Jan 4, 2023, 8:01:14 PM1/4/23
to wx-users
Hey everyone,

I posted this question on the wxWidgets Forum, and they told me to come here, so here I am.

It seems like others have been able to successfully build wxWidgets for both Intel and Apple Silicon Macs by adding the 
--enable-universal_binary=x86_64,arm64 
flag to their configure command. That works fine for me, but when I run 'make', I get this error:
ld: warning: dylib (/usr/local/Cellar/pcre2/10.42/lib/libpcre2-32.dylib) was built for newer macOS version (12.0) than being linked (10.10) ld: warning: ignoring file /usr/local/Cellar/pcre2/10.42/lib/libpcre2-32.dylib, building for macOS-arm64 but attempting to link with file built for macOS-x86_64 Undefined symbols for architecture arm64: "_pcre2_code_free_32", referenced from: wxRegExImpl::~wxRegExImpl() in basedll_regex.o wxRegExImpl::~wxRegExImpl() in basedll_regex.o wxRegExImpl::Compile(wxString, int) in basedll_regex.o wxRegEx::~wxRegEx() in basedll_regex.o wxRegEx::Compile(wxString const&, int) in basedll_regex.o "_pcre2_compile_32", referenced from: wxRegExImpl::Compile(wxString, int) in basedll_regex.o "_pcre2_config_32", referenced from: wxRegEx::GetLibraryVersionInfo() in basedll_regex.o "_pcre2_get_error_message_32", referenced from: (anonymous namespace)::wx_regerror(int, (anonymous namespace)::regex_t const*, wchar_t*, unsigned long) in basedll_regex.o "_pcre2_get_ovector_pointer_32", referenced from: wxRegExImpl::Matches(wchar_t const*, int, unsigned long) const in basedll_regex.o "_pcre2_match_32", referenced from: wxRegExImpl::Matches(wchar_t const*, int, unsigned long) const in basedll_regex.o "_pcre2_match_data_create_from_pattern_32", referenced from: wxRegExImpl::Compile(wxString, int) in basedll_regex.o "_pcre2_match_data_free_32", referenced from: wxRegExImpl::~wxRegExImpl() in basedll_regex.o wxRegExImpl::~wxRegExImpl() in basedll_regex.o wxRegExImpl::Compile(wxString, int) in basedll_regex.o wxRegEx::~wxRegEx() in basedll_regex.o wxRegEx::Compile(wxString const&, int) in basedll_regex.o ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [/Users/camera/Downloads/wx_from_git/wxWidgets/buildOSX/lib/libwx_baseu-3.3.0.0.0.dylib] Error 1
I'm using an Intel Mac running MacOS Monterey 12.6.2 (the latest version Apple will let me install on my laptop). I cloned the latest version of wxWidgets (3.3.0 at the time of writing) with by using this command:
git clone --recurse-submodules https://github.com/wxWidgets/wxWidgets.git
Homebrew says my pcre2 library is up-to-date. I even tried reinstalling it to no avail. The pcre2 page on the homebrew website says it works on both x86_64 and arm64, but when I run the file command in terminal:
file libpcre2-32.0.dylib
libpcre2-32.0.dylib: Mach-O 64-bit dynamically linked shared library x86_64
It mentions nothing of arm64. 

Interestingly enough, when I add the --disable-shared flag to the configure command, I get no errors when I run 'make', but it generates .a files, which apparently I can't use on Mac.

How have others built .dylibs for both architectures and avoided this issue?

David Connet

unread,
Jan 4, 2023, 8:23:10 PM1/4/23
to wx-u...@googlegroups.com
On 1/4/2023 4:57 PM, Henry M wrote:
Hey everyone,

I posted this question on the wxWidgets Forum, and they told me to come here, so here I am.

It seems like others have been able to successfully build wxWidgets for both Intel and Apple Silicon Macs by adding the 
--enable-universal_binary=x86_64,arm64

I'm doing it with --enable-macosx_arch=x86_64,arm64

Dave

Vadim Zeitlin

unread,
Jan 4, 2023, 8:24:49 PM1/4/23
to wx-u...@googlegroups.com
On Wed, 4 Jan 2023 16:57:30 -0800 (PST) Henry M wrote:

HM> Hey everyone,
HM>
HM> I posted this question on the wxWidgets Forum, and they told me to come
HM> here, so here I am.

Hello and welcome to the list!

HM> It seems like others have been able to successfully build wxWidgets for
HM> both Intel and Apple Silicon Macs by adding the
HM> --enable-universal_binary=x86_64,arm64

Yes, this works without problems (well, unless you use an ancient SDK, but
this isn't your case).

HM> flag to their configure command. That works fine for me, but when I run
HM> 'make', I get this error:
HM> ld: warning: dylib (/usr/local/Cellar/pcre2/10.42/lib/libpcre2-32.dylib)
HM> was built for newer macOS version (12.0) than being linked (10.10) ld:
HM> warning: ignoring file /usr/local/Cellar/pcre2/10.42/lib/libpcre2-32.dylib,
HM> building for macOS-arm64 but attempting to link with file built for
HM> macOS-x86_64

The simplest solution is to disable the use of this library, as you
probably don't want to depend on it anyhow -- if you're building a
universal binary, it's probably because you want to distribute it and
it shouldn't depend on any libraries from your system.

So you should rerun configure with --disable-sys-libs option and check
that the summary at the end shows that only built-in libraries are used.
Rebuilding after doing this should work.

HM> Interestingly enough, when I add the --disable-shared flag to the configure
HM> command, I get no errors when I run 'make', but it generates .a files,
HM> which apparently I can't use on Mac.

You can use them, of course, why do you think you can't?

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

Vadim Zeitlin

unread,
Jan 4, 2023, 8:26:23 PM1/4/23
to wx-u...@googlegroups.com
On Wed, 4 Jan 2023 17:23:05 -0800 David Connet wrote:

DC> On 1/4/2023 4:57 PM, Henry M wrote:
DC> > Hey everyone,
DC> >
DC> > I posted this question on the wxWidgets Forum, and they told me to
DC> > come here, so here I am.
DC> >
DC> > It seems like others have been able to successfully build wxWidgets
DC> > for both Intel and Apple Silicon Macs by adding the
DC> > --enable-universal_binary=x86_64,arm64
DC>
DC> I'm doing it with --enable-macosx_arch=x86_64,arm64

It's a bit confusing that both of these options exist, but they both work.
The (only, AFAICS) difference between them is that you don't need to
specify the value for --enable-universal_binary, i.e. you can just use it
as is, while you always need to specify the architectures you want to use
explicitly with --enable-macosx_arch.

Henry M

unread,
Jan 4, 2023, 10:16:38 PM1/4/23
to wx-users
Thank you both for your quick responses!

I tried the --disable-sys-libs option, and unfortunately, that gives me new errors

Undefined symbols for architecture x86_64:

  "_crc32", referenced from:

      wxZipInputStream::OpenDecompressor(bool) in basedll_zipstrm.o

      wxZipInputStream::OnSysRead(void*, unsigned long) in basedll_zipstrm.o

      wxZipOutputStream::DoCreate(wxZipEntry*, bool) in basedll_zipstrm.o

      wxZipOutputStream::CreatePendingEntry() in basedll_zipstrm.o

      wxZipOutputStream::OnSysWrite(void const*, unsigned long) in basedll_zipstrm.o

  "_deflate", referenced from:

      wxZlibOutputStream::DoFlush(bool) in basedll_zstream.o

      wxZlibOutputStream::OnSysWrite(void const*, unsigned long) in basedll_zstream.o

  "_deflateEnd", referenced from:

      wxZlibOutputStream::Close() in basedll_zstream.o

      wxZlibOutputStream::~wxZlibOutputStream() in basedll_zstream.o

  "_deflateInit2_", referenced from:

      wxZlibOutputStream::Init(int, int) in basedll_zstream.o

  "_deflateReset", referenced from:

      wxZlibOutputStream2::Open(wxOutputStream&) in basedll_zipstrm.o

  "_deflateSetDictionary", referenced from:

      wxZlibOutputStream::SetDictionary(char const*, unsigned long) in basedll_zstream.o

      wxZlibOutputStream::SetDictionary(wxMemoryBuffer const&) in basedll_zstream.o

  "_inflate", referenced from:

      wxZlibInputStream::OnSysRead(void*, unsigned long) in basedll_zstream.o

  "_inflateEnd", referenced from:

      wxZlibInputStream::~wxZlibInputStream() in basedll_zstream.o

      wxZlibInputStream::~wxZlibInputStream() in basedll_zstream.o

      wxZlibInputStream::~wxZlibInputStream() in basedll_zstream.o

  "_inflateInit2_", referenced from:

      wxZlibInputStream::Init(int) in basedll_zstream.o

  "_inflateReset", referenced from:

      wxZlibInputStream2::Open(wxInputStream&) in basedll_zipstrm.o

  "_inflateSetDictionary", referenced from:

      wxZlibInputStream::SetDictionary(char const*, unsigned long) in basedll_zstream.o

      wxZlibInputStream::SetDictionary(wxMemoryBuffer const&) in basedll_zstream.o

  "_zlibVersion", referenced from:

      wxGetZlibVersionInfo() in basedll_zstream.o

      wxGzipClassFactory::wxGzipClassFactory() in basedll_zstream.o

      wxZlibInputStream::CanHandleGZip() in basedll_zstream.o

      wxZlibInputStream::Init(int) in basedll_zstream.o

      wxZlibOutputStream::Init(int, int) in basedll_zstream.o

      wxZlibOutputStream::CanHandleGZip() in basedll_zstream.o

ld: symbol(s) not found for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

make: *** [/Users/camera/Downloads/wx_from_git/wxWidgets/buildOSX/lib/libwx_baseu-3.3.0.0.0.dylib] Error 1

Is there a Zlib library I'm now missing because of the --disable-sys-libs flag? If so, where do I put it so that 'make' can find it ?

P.S. This post on stackoverflow gave me the impression that statically linking libraries is either not possible or frowned upon on Mac

Vadim Zeitlin

unread,
Jan 5, 2023, 10:53:21 AM1/5/23
to wx-u...@googlegroups.com
On Wed, 4 Jan 2023 19:16:38 -0800 (PST) Henry M wrote:

HM> Thank you both for your quick responses!
HM>
HM> I tried the --disable-sys-libs option, and unfortunately, that gives me new
HM> errors
HM>
HM> Undefined symbols for architecture x86_64:
HM>
HM> "_crc32", referenced from:

It looks like zlib is not being linked but I don't know why. You need to
go back and give us:

1. Your full configure command line.
2. The result of configure check for zlib (summary at the end).
3. Full link command which fails.

HM> Is there a Zlib library I'm now missing because of the
HM> --disable-sys-libs flag? If so, where do I put it so that 'make' can find
HM> it ?

This library, as well as all the others, is included in wxWidgets as a
submodule so you should already have it and it should have been built as
part of the build with --disable-sys-libs. But clearly something went wrong
at some stage. You should look at configure output and maybe config.log to
find out what.

HM> P.S. This post on stackoverflow
HM> <https://stackoverflow.com/questions/844819/how-to-static-link-on-os-x> gave
HM> me the impression that statically linking libraries is either not possible
HM> or frowned upon on Mac

This question is about statically linking the CRT which is quite different
from statically linking wxWidgets, which is perfectly possible and, to the
best of my knowledge, allowed even in most polite company.

Henry M

unread,
Jan 5, 2023, 12:24:14 PM1/5/23
to wx-users

VZ> to the best of my knowledge, allowed even in most polite company.

Haha! Good to know. I think I'd rather use the .dylibs because XCode threw a bunch of 'undefined symbol' errors when I tried to link the static libraries, and I would prefer to not troubleshoot XCode linker errors.

VZ> It looks like zlib is not being linked but I don't know why. You need to
VZ> go back and give us:
VZ>
VZ> 1. Your full configure command line.
VZ> 2. The result of configure check for zlib (summary at the end).
VZ> 3. Full link command which fails.

1. ../configure --disable-sys-libs --enable-macosx_arch=x86_64,arm64
2. Which libraries should wxWidgets use?  zlib               builtin
3. g++ -std=gnu++11 -mmacosx-version-min=12.0 -dynamiclib -single_module -headerpad_max_install_names -o /Users/camera/Downloads/wx_from_git/wxWidgets/buildOSX/lib/libwx_baseu-3.3.0.0.0.dylib  basedll_any.o basedll_appbase.o basedll_arcall.o basedll_arcfind.o basedll_archive.o basedll_arrstr.o basedll_base64.o basedll_clntdata.o basedll_cmdline.o basedll_config.o basedll_convauto.o basedll_datetime.o basedll_datetimefmt.o basedll_datstrm.o basedll_dircmn.o basedll_dynlib.o basedll_dynload.o basedll_encconv.o basedll_evtloopcmn.o basedll_extended.o basedll_ffile.o basedll_file.o basedll_fileback.o basedll_fileconf.o basedll_filefn.o basedll_filename.o basedll_filesys.o basedll_filtall.o basedll_filtfind.o basedll_fmapbase.o basedll_fs_arc.o basedll_fs_filter.o basedll_hash.o basedll_hashmap.o basedll_init.o basedll_intl.o basedll_ipcbase.o basedll_languageinfo.o basedll_list.o basedll_log.o basedll_longlong.o basedll_memory.o basedll_mimecmn.o basedll_module.o basedll_mstream.o basedll_numformatter.o basedll_object.o basedll_platinfo.o basedll_powercmn.o basedll_process.o basedll_regex.o basedll_stdpbase.o basedll_sstream.o basedll_stdstream.o basedll_stopwatch.o basedll_strconv.o basedll_stream.o basedll_string.o basedll_stringops.o basedll_strvararg.o basedll_sysopt.o basedll_tarstrm.o basedll_textbuf.o basedll_textfile.o basedll_threadinfo.o basedll_time.o basedll_timercmn.o basedll_timerimpl.o basedll_tokenzr.o basedll_translation.o basedll_txtstrm.o basedll_unichar.o basedll_uri.o basedll_ustring.o basedll_variant.o basedll_wfstream.o basedll_wxcrt.o basedll_wxprintf.o basedll_xlocale.o basedll_xti.o basedll_xtistrm.o basedll_zipstrm.o basedll_zstream.o basedll_fswatchercmn.o basedll_fswatcherg.o basedll_common_secretstore.o basedll_lzmastream.o basedll_common_uilocale.o basedll_core_mimetype.o basedll_cfstring.o basedll_evtloop_cf.o basedll_strconv_cf.o basedll_utils_base.o basedll_core_secretstore.o basedll_core_uilocale.o basedll_fdiodispatcher.o basedll_selectdispatcher.o basedll_appunix.o basedll_unix_dir.o basedll_dlunix.o basedll_epolldispatcher.o basedll_evtloopunix.o basedll_fdiounix.o basedll_unix_snglinst.o basedll_unix_stackwalk.o basedll_timerunx.o basedll_threadpsx.o basedll_utilsunx.o basedll_wakeuppipe.o basedll_fswatcher_kqueue.o basedll_fswatcher_fsevents.o basedll_cocoa_stdpaths.o basedll_event.o basedll_fs_mem.o basedll_msgout.o basedll_utilscmn.o  basedll_cocoa_power.o basedll_cocoa_utils.o basedll_osx_volume.o    -L/Users/camera/Downloads/wx_from_git/wxWidgets/buildOSX/lib -install_name /usr/local/lib/libwx_baseu-3.3.0.dylib   -compatibility_version 1.0 -current_version 1.0   -arch x86_64 -arch arm64 -framework IOKit -framework Carbon -framework Cocoa -framework QuartzCore -framework AudioToolbox -framework System -framework OpenGL  -lwxzlib-3.3 -lwxregexu-3.3 -lwxexpat-3.3 -arch x86_64 -arch arm64  -framework IOKit -framework Carbon -framework Cocoa -framework QuartzCore -framework AudioToolbox -framework System -framework OpenGL  -framework Security -lpthread -liconv -lcurl   -framework Security -lpthread -liconv -lcurl

––––––––––––––––––––––––––––––––––––––––––––––––––––––

It looks like it's including the zlib library. However, I also noticed this line in the configure output:   libdeflate support:                 no
^ could this be the issue? I tried '--enable-libdeflate' but that wasn't recognized. Is there a flag that would remedy it?


Vadim Zeitlin

unread,
Jan 5, 2023, 1:08:07 PM1/5/23
to wx-u...@googlegroups.com
On Thu, 5 Jan 2023 09:24:14 -0800 (PST) Henry M wrote:

HM> Haha! Good to know. I think I'd rather use the .dylibs because XCode threw
HM> a bunch of 'undefined symbol' errors when I tried to link the static
HM> libraries, and I would prefer to not troubleshoot XCode linker errors.

There should be no problems using either.

HM> VZ> It looks like zlib is not being linked but I don't know why. You need to
HM> VZ> go back and give us:
HM> VZ>
HM> VZ> 1. Your full configure command line.
HM> VZ> 2. The result of configure check for zlib (summary at the end).
HM> VZ> 3. Full link command which fails.
HM>
HM> 1. ../configure --disable-sys-libs --enable-macosx_arch=x86_64,arm64
HM> 2. Which libraries should wxWidgets use? zlib builtin
HM> 3. g++ -std=gnu++11 -mmacosx-version-min=12.0 -dynamiclib -single_module
[...]
HM> -framework System -framework OpenGL -lwxzlib-3.3 -lwxregexu-3.3

Sorry, I can't explain what's going wrong here, everything looks correct.
Are you rebuilding in the same directory you had previously used for the
build with the other options? If so, I recommend doing "rm -rf" on it,
creating a new build directory (you can use the same name for it, of
course) and then redoing configure and make. It really ought to work out of
the box.

HM> It looks like it's including the zlib library. However, I also noticed this
HM> line in the configure output: libdeflate support: no
HM> ^ could this be the issue?

No, this just means that this library is not used. You're getting link
errors for zlib symbols which shouldn't be referenced at all as our zlib
uses "wx" prefix for its symbols.

I really think that redoing the process in a new directory (or maybe just
after "make clean", but nuking the entire directory is even more reliable)
should result in a successful build.

Good luck,

Henry M

unread,
Jan 5, 2023, 5:20:04 PM1/5/23
to wx-users
VZ> I really think that redoing the process in a new directory (or maybe just
VZ> after "make clean", but nuking the entire directory is even more reliable)
VZ> should result in a successful build.

Wow. This took me back to my first CS class in college. Yes, cleaning out the directory and building from scratch did the trick. Apologies for my ignorance!

David Connet

unread,
Jan 5, 2023, 5:30:31 PM1/5/23
to wx-u...@googlegroups.com
On 1/5/2023 2:20 PM, Henry M wrote:
> Wow. This took me back to my first CS class in college. Yes, cleaning
> out the directory and building from scratch did the trick. Apologies
> for my ignorance!

LOL! I've learned (the hard way, of course) to always try that before
raising an issue now. And, no, I'm not talking about wxWidgets - I'm
talking about the company I work for!

Dave

Henry M

unread,
Jan 6, 2023, 5:56:35 PM1/6/23
to wx-users
Dave> (LOL! I've learned (the hard way, of course) to always try that before)
Dave> (raising an issue now. And, no, I'm not talking about wxWidgets - I'm)
Dave> (talking about the company I work for!)

Learning the hard way is always fun, isn't it?

Also, sorry to revive this thread, but my compiled app isn't running on other computers.
Screen Shot 2023-01-06 at 2.41.47 PM.png
when I run otool -l on that library, it shows this:

cmd LC_ID_DYLIB
cmdsize 112
name /Users/camera/Downloads/wx_from_git/wxWidgets/buildOSX/lib/libwx_baseu-3.3.0.0.0.dylib (offset 24)
time stamp 1 Wed Dec 31 16:00:01 1969

They're all like that. I originally built the libraries in that location, but obviously I don't want the path hardcoded there. I tried changing it manually with install_name_tool but it told me I would be invalidating the code signature by doing so.

Is this something I can fix when building wxWidgets? 

Vadim Zeitlin

unread,
Jan 7, 2023, 11:54:24 AM1/7/23
to wx-u...@googlegroups.com
On Fri, 6 Jan 2023 14:56:35 -0800 (PST) Henry M wrote:

HM> Also, sorry to revive this thread, but my compiled app isn't running on
HM> other computers.

This one of the reasons people prefer to link statically for distribution.

HM> [image: Screen Shot 2023-01-06 at 2.41.47 PM.png]

There is really no need to post text as screenshots...

HM> They're all like that. I originally built the libraries in that location,
HM> but obviously I don't want the path hardcoded there. I tried changing it
HM> manually with install_name_tool but it told me I would be invalidating the
HM> code signature by doing so.

This is the right thing to do, but you need to run install_name_tool
before signing. You will also want to use relative path in the name you
pass to it and put the shared libraries inside your application bundle
where they can always be found.

Regards,

Henry M

unread,
Jan 13, 2023, 2:05:55 PM1/13/23
to wx-users
That's what I ended up doing. I was just hoping there was a way to configure it in the build process because it took a good chunk of time to run install_name_tool multiple times on each .dylib file. 

Anyways, thank you again for all your help!

Vadim Zeitlin

unread,
Jan 14, 2023, 8:44:40 AM1/14/23
to wx-u...@googlegroups.com
On Fri, 13 Jan 2023 11:05:55 -0800 (PST) Henry M wrote:

HM> That's what I ended up doing. I was just hoping there was a way to
HM> configure it in the build process because it took a good chunk of time to
HM> run install_name_tool multiple times on each .dylib file.

This is surprising, I've never seen it taking a noticeable amount of time.
Normally it just rewrites a few bytes in the header, so I have trouble
understanding why would this happen in your case.

Anyhow, we could avoid having to run install_name_tool if we specified the
desired rpath when linking the library directly. So it could be nice to add
some option to specify rpath to configure (--with-rpath?), so that you
could specify --with-rpath=@executable_path/../Libraries if you embed the
libraries into this directory of your bundle. I don't plan on doing it
myself right now, but any patches adding such an option would be welcome!
Reply all
Reply to author
Forward
0 new messages