• Hello MLAers! We've re-enabled auto-approval for accounts. If you are still waiting on account approval, please check this thread for more information.

Retro68 build issues.

Snial

68000
Hi folks,

I've just been trying to install Retro68, but it fell over somewhere when trying to link. As per the instructions, the first thing I did was:

brew install boost cmake gmp mpfr libmpc bison texinfo

Then there were some more commands ending in: ../Retro68/build-toolchain.bash . There was lots of spew from the build process, which eventually ended in:

Code:
[ 71%] Linking CXX executable ResInfo
Undefined symbols for architecture arm64:
  "boost::filesystem::path::append_v3(char const*, char const*)", referenced from:
etc until it got to:
Code:
ld: symbol(s) not found for architecture arm64
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

Usually this happens when some of the building process expects Arm64, but instead x64 stuff (or nothing) has been installed. Here it implies it's boost. There's certainly lots of .o files in the build directories, so it's getting quite a long way. I figured I should check whether my tools are ARM64 (I ran these commands after I cd'd to the PceMacCP directory)..

Julians-MacBook-Pro: PceMacCP julianskidmore$ which -a brew
/opt/homebrew/bin/brew (this means it's ARM64)
/usr/local/bin/brew
Julians-MacBook-Pro: PceMacCP julianskidmore$ brew config
<snip1>
CPU: octa-core 64-bit arm_blizzard_avalanche (seems to think it's installing for ARM64)
<snip1>
macOS: 15.5-arm64 (seems to think it's installing for ARM64)
<snip1>

Rosetta 2: false
Julians-MacBook-Pro: PceMacCP julianskidmore$ ld -v
<snip2>. (ld seems to think it can link for ARM)

configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
will use ld-classic for: armv6 armv7 armv7s i386 armv6m armv7k armv7m armv7em
<snip2>

Julians-MacBook-Pro: PceMacCP julianskidmore$ g++ -v
Apple clang version 17.0.0 (clang-1700.0.13.5)
Target: arm64-apple-darwin24.5.0 (g++ compiles to ARM64)
<snip3>
Julians-MacBook-Pro: PceMacCP julianskidmore$ gcc -v
Apple clang version 17.0.0 (clang-1700.0.13.5)
Target: arm64-apple-darwin24.5.0 (gcc will compile to ARM64)


However, it looks like some ARM64 support is missing for the build, and that boost is at least one of the libraries not properly installed. After some trawling I found that typing brew info boost told me it was in /opt/homebrew/Cellar/boost/1.88.0. OK, I know that I've installed an ARM64 version of Boost, by uninstalling it and re-installing it whereupon it said:

Pouring boost--1.88.0.arm64_sequoia.bottle.tar.gz

OK, so I tried re-running ../Retro68/build-toolchain.bash and a million lines of spew appeared as expected. Amongst all the sick I could occasionally see that it was trying to build for aarch64 (or arm64, it sped by so fast it was hard to tell) and after several minutes, just as before it vomited the same error message.

Any idea what's wrong?


<Snip1
HOMEBREW_VERSION: 4.5.12
ORIGIN: https://github.com/Homebrew/brew
HEAD: 50fa89e96bccedeca21287427eb7db12289f57ea
Last commit: 3 days ago
Branch: stable
Core tap JSON: 26 Jul 12:00 UTC
Core cask tap JSON: 26 Jul 12:00 UTC
HOMEBREW_PREFIX: /opt/homebrew
HOMEBREW_CASK_OPTS: []
HOMEBREW_DISPLAY: /private/tmp/com.apple.launchd.eZzpRYSkib/org.xquartz:0
HOMEBREW_MAKE_JOBS: 8
Homebrew Ruby: 3.4.5 => /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.4.5/bin/ruby
..
CLT: 16.4.0.0.1.1747106510
Xcode: 16.4
..
CLT: 16.4.0.0.1.1747106510
Xcode: 16.4>
<snip2
@(#)PROGRAM:ld PROJECT:ld-1167.5
BUILD 01:45:05 Apr 30 2025
..
LTO support using: LLVM version 17.0.0 (static support for 29, runtime is 29)
TAPI support using: Apple TAPI version 17.0.0 (tapi-1700.0.3.5)>
<snip3
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
>
 
Can you figure out which boost library or libraries specifically it's trying to link against? I don't recall if retro68's building echos every command it's executing, though given how much output it produces it probably does, and that means you should be able to look at the failing command and see which libraries it's attempting to link to.

If you can find them, try confirming they are arm64 with the file command, something like:
file /opt/homebrew/Cellar/boost/1.88.0/lib/boost.dylib
(That's not the right path, but substitute the exact path that the command uses)
That'll at least confirm the actual architecture of the library as it is on disk. I know homebrew can have some funky behavior sometimes so it's not impossible you've got an x86_64 library mixed in there for some reason.

Alternatively, you might find it's *not* linking to any boost library which would also at least partly explain what's going wrong.
 
Can you figure out which boost library or libraries specifically it's trying to link against? I don't recall if retro68's building echos every command it's executing, though given how much output it produces it probably does, and that means you should be able to look at the failing command and see which libraries it's attempting to link to.

If you can find them, try confirming they are arm64 with the file command, something like:
file /opt/homebrew/Cellar/boost/1.88.0/lib/boost.dylib
(That's not the right path, but substitute the exact path that the command uses)
That'll at least confirm the actual architecture of the library as it is on disk. I know homebrew can have some funky behavior sometimes so it's not impossible you've got an x86_64 library mixed in there for some reason.

Alternatively, you might find it's *not* linking to any boost library which would also at least partly explain what's going wrong.
Hi @bribri,

Thanks for the response. I tried file /opt/homebrew/Cellar/boost/1.88.0/lib/*.dylib and got this:

/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_atomic.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_charconv.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_chrono.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_container.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_context.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_contract.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_coroutine.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_date_time.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_fiber.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_filesystem.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_graph.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_iostreams.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_json.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_locale.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_log_setup.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_log.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_math_c99.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_math_c99f.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_math_c99l.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_math_tr1.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_math_tr1f.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_math_tr1l.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_nowide.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_prg_exec_monitor.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_process.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_program_options.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_random.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_regex.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_serialization.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_stacktrace_addr2line.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_stacktrace_basic.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_stacktrace_noop.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_system.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_thread.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_timer.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_type_erasure.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_unit_test_framework.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_url.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_wave.dylib: Mach-O 64-bit dynamically linked shared library arm64
/opt/homebrew/Cellar/boost/1.88.0/lib/libboost_wserialization.dylib: Mach-O 64-bit dynamically linked shared library arm64


Is that what you meant? It all looks like arm64 to me! Hmm, I know the instruction for installing Retro68 included brew install Boost, so I guess it does use it.
 
That rules out something being the wrong architecture. Can you post the compilation command that's generating the error?
 
That rules out something being the wrong architecture. Can you post the compilation command that's generating the error?
I'm not sure how to do that. What I could do is create a simple program that uses the line it fell over at:

"boost::filesystem::path::append_v3(char const*, char const*)", referenced from:

(See OP). I've never compiled anything with Boost before, not sure of the simplest example to do that. I'm thinking of a program of the form:

C++:
#include <stdio.h>
#include <BoostSomethingOrAnother.h>

int main(void)
{
    /* The simplest program that uses boost::filesystem::path::append_v3 */
    return 0;
}

And a gcc (or g++) command that compiles it and links boost, something of the form: gcc -l boost_filesystem.dylib boostTest.cpp -o boostTest .

That would at least prove the symbols do exist for boost when compiling for ARM64.
 
@bribri , @Mu0n . I can give an example of frustration with modern tools.

I want to know how to compile a simple Boost example. So, I googled "C++ Boost example". Indeed, it leads to some example code:


But when you click on them, although it provides source code it doesn't tell you how to compile it and link in the library.


Now I have to go and search for that. It's classic: "Here's some help for people who already know enough not to need it." OK, so then I searched on how to link it, which helpfully said that for most Boost libraries you don't need to link it. That's not true for the filesystem Boost library, which is the issue here. Instead I found this page on getting started:


It tells me to set up an example program by cd boost-root/libs/filesystem/example/test. I think boost-root on my Mac is: /opt/homebrew/Cellar/boost/1.88.0/. However, there's no subdirectory called libs (only lib).

I found this page: https://uvdn7.github.io/boost-darwin/ where someone was trying to install it (in the Intel days) and found homebrew didn't do the job; so the author had to install it manually. However, Retro68 explicitly says that we should install via HomeBrew, so it must be possible to make it work - if only I had an example to try!!!!!

Then I found this page: https://pyimagesearch.com/2015/04/27/installing-boost-and-boost-python-on-osx-with-homebrew/

It says: "I really, really hope that someone finds this resource useful. The amount of time I have wasted over the past few months (passively) trying to get boost and boost-python to install on my OSX machine via Homebrew has been nothing short of excruciating."

So, I'm not alone. But, this person is interested in Boost with python and I don't care about downloading that, because... it's not trying to link into python on Retro68 is it?

Another web page talks about issues with installing Boost, but this is for 'Conda'. The error message they had was similar to mine:


Their solution was to remove Boost. That makes no sense to me given Boost is a dependancy. Then I came across this, a web page telling you how to find the Boost package if you're using cmake: https://cmake.org/cmake/help/latest/module/FindBoost.html

I would have thought this was a command line option, but it's not; it's either source code or some kind of cmake internal script. So, if I was to use this, I'd have to know how to incorporate that into a cmake... whatever, but I'm not familiar with cmake, I just treat it as a pile of turds that have to be used because someone didn't want to use make.

So, the frustration continues. OK, next up. I found this:


I think it tells me how to compile and link something with Boost. I can see that /usr/local/include/boost exists, so that's a bit of progress. Finally:

$clang++ -I/usr/local/include -L/usr/local/lib -lboost_system boost_test.cpp
ld: warning: ignoring file '/usr/local/lib/libboost_system.dylib': found architecture 'x86_64', required architecture 'arm64'


So, it does look like /usr/local/lib/'s lib boost is x64, not ARM64.
 
That feeling of being outside, looking in? Check.
That feeling that all guides online become obsolete after a year but are still up 5 years after their time? Check.

I'm not particularly fond of doing the work to change compiling tools. More power to those who thrive on it and magically understand what to do with dependency hell.
 
@bribri , @Mu0n . OK, so I think I'm making progress.

$ lipo -info /usr/local/lib/libboost_filesystem.dylib
Non-fat file: /usr/local/lib/libboost_filesystem.dylib is architecture: x86_64

$lipo -info /opt/homebrew/Cellar/boost/1.88.0/lib/libboost_filesystem.dylib
Non-fat file: /opt/homebrew/Cellar/boost/1.88.0/lib/libboost_filesystem.dylib is architecture: arm64


It seems like it's possible to use lipo to combine them. What could go wrong ;-) ?


$lipo /opt/homebrew/Cellar/boost/1.88.0/lib/libboost_filesystem.dylib /usr/local/lib/libboost_filesystem.dylib -create -output /usr/local/lib/libboost_filesystem2.dylib

OK, no error there.

$ lipo -info /usr/local/lib/libboost_filesystem2.dylib
Architectures in the fat file: /usr/local/lib/libboost_filesystem2.dylib are: x86_64 arm64


Finally, a universal library! I wonder if I can just do the same thing but overwrite libboost_filesystem.dylib instead of creating libboost_filesystem2.dylib without crashing?

That feeling of being outside, looking in? Check.
That feeling that all guides online become obsolete after a year but are still up 5 years after their time? Check.
I'm not particularly fond of doing the work to change compiling tools. More power to those who thrive on it and magically understand what to do with dependency hell.
I'll find out in a minute when I modify the command and my MacBook M2 hangs!
 
Well, it didn't blow up, however, I still have the same problem when building Retro68:

-- Found Boost: /opt/homebrew/lib/cmake/Boost-1.88.0/BoostConfig.cmake (found version "1.88.0") found components: filesystem program_options
-- Configuring done (0.2s)
-- Generating done (0.1s)
-- Build files have been written to: /Users/julianskidmore/Development/Retro68Dev/Retro68-build/build-host
[ 67%] Built target ELF
[ 68%] Building CXX object ResourceFiles/CMakeFiles/ResourceFiles.dir/ResourceFile.cc.o
/Users/julianskidmore/Development/Retro68Dev/Retro68/ResourceFiles/ResourceFile.cc:83:10: warning: unused variable 'timestamp' [-Wunused-variable]
83 | auto timestamp = std::invoke([&]()-> std::chrono::system_clock::time_point {
| ^~~~~~~~~
1 warning generated.
[ 68%] Linking CXX static library libResourceFiles.a
[ 69%] Built target ResourceFiles
[ 70%] Linking CXX executable ResInfo
Undefined symbols for architecture arm64:
"boost::filesystem::path::append_v3(char const*, char const*)", referenced from:
ResourceFile::assign(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, ResourceFile::Format) in libResourceFiles.a[5](ResourceFile.cc.o)


OK, so this time, I can see it's found Boost where homebrew expects it to be. Yet, it still bombs with the same error.
 
A minor improvement. I deleted the entire build tree in case it was trying to use a library it thought it had already built. I then re-ran the build for Retro68. It fell over just like before. This time though I've found the link command that caused the failure.

/usr/bin/c++ -Wall -Werror=return-type -Wno-multichar -g -arch arm64 -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/ResInfo.dir/ResInfo.cc.o -o ResInfo libResourceFiles.a /opt/homebrew/lib/libboost_program_options.dylib /opt/homebrew/lib/libboost_filesystem.dylib /opt/homebrew/lib/libboost_atomic.dylib /opt/homebrew/lib/libboost_system.dylib /Users/julianskidmore/Development/Retro68Dev/Retro68-build/toolchain/lib/libhfs.a

I've done lipo -info on all of the objects, libraries and dylibs here, and they're all arm64. So, the mystery gets deeper again. Though... hang on, I think I've found the problem... "boost::filesystem .." has a 😛 in the middle of the path as you can see above! It won't compile out of pure cheek!
 
OK. I've made a bit more progress. You can list the symbols in a dylib using nm -gU libraryName.dylib . Because I knew I had an x64 and arm64 version of libboost_filesystem.dylib , I figured I could list the symbols for each architecture; pipe them to grep "append" , because it was an append function that couldn't be linked and then diff them.

I had to re-extract the x64 version first though, because I'd merged it with the arm64 version earlier.

$ lipo /usr/local/lib/libboost_filesystem.dylib -extract x86_64 -output BoostFs.dylib
$ nm -gU BoostFs.dylib | grep "append" > AppendUsrLocalX64.txt
$ nm -gU /opt/homebrew/lib/libboost_filesystem.dylib | grep "append" > AppendHomebrew.txt
$ diff AppendHomebrew.txt AppendUsrLocalX64.txt
1,3c1,3
< 000000000000f774 T __ZN5boost10filesystem6detail15path_algorithms26append_separator_if_neededERNS0_4pathE
< 0000000000010118 T __ZN5boost10filesystem6detail15path_algorithms9append_v3ERNS0_4pathEPKcS6_
< 0000000000010604 T __ZN5boost10filesystem6detail15path_algorithms9append_v4ERNS0_4pathEPKcS6_
---
> 000000000000fb40 T __ZN5boost10filesystem4path26append_separator_if_neededEv
> 000000000000f9d0 T __ZN5boost10filesystem4path9append_v3EPKcS3_
> 000000000000fee0 T __ZN5boost10filesystem4path9append_v4EPKcS3_


So, at last, there's something that appears to be different. Here's a request then, for those of you who have retro68 working on an ARM Macintosh (e.g. @MIST , @David Cook , @Mu0n , @bribri , @noglin ?). Could you find the link command where it failed for me (assuming the build files don't get deleted by a clean-up stage)...

cat pathTo/Retro68-build/build-host/ResourceFiles/CMakeFiles/ResInfo.dir/link.txt

Check it's an ARM64 library (replace my path to libboost_filesystem.dylib below with the path described in your link.txt):
$ lipo -info /opt/homebrew/lib/libboost_filesystem.dylib
Non-fat file: /opt/homebrew/lib/libboost_filesystem.dylib is architecture: arm64


List the append symbols (again for your version of libboost_filesystem.dylib as in the previous command):
$ nm -gU /opt/homebrew/lib/libboost_filesystem.dylib | grep "append"
000000000000f774 T __ZN5boost10filesystem6detail15path_algorithms26append_separator_if_neededERNS0_4pathE
0000000000010118 T __ZN5boost10filesystem6detail15path_algorithms9append_v3ERNS0_4pathEPKcS6_
0000000000010604 T __ZN5boost10filesystem6detail15path_algorithms9append_v4ERNS0_4pathEPKcS6_


Then I'll know if you've got different ARM64 symbols for libboost_filesystem.dylib compared to me.

-cheers from Julz
 
Hey @Snial, I've been missing this thread, feel free to ping my name so I get notified. This is what I get:
lipo -info /opt/homebrew/lib/libboost_filesystem.dylib
Non-fat file: /opt/homebrew/lib/libboost_filesystem.dylib is architecture: arm64

% nm -gU /opt/homebrew/lib/libboost_filesystem.dylib | grep "append"
000000000000f774 T __ZN5boost10filesystem6detail15path_algorithms26append_separator_if_neededERNS0_4pathE
0000000000010118 T __ZN5boost10filesystem6detail15path_algorithms9append_v3ERNS0_4pathEPKcS6_
0000000000010604 T __ZN5boost10filesystem6detail15path_algorithms9append_v4ERNS0_4pathEPKcS6_
brew info boost
==> boost: stable 1.88.0 (bottled), HEAD
Collection of portable C++ source libraries
Installed
/opt/homebrew/Cellar/boost/1.88.0 (16,266 files, 346.2MB) *
Poured from bottle using the formulae.brew.sh API on 2025-05-11 at 17:32:09
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/b/boost.rb

I really did not have any problems compiling retro68k myself.

I didn't read the whole thread in detail. I would recommend to wipe brew completely, delete your Retro68-build and redo it.
 
Hey @Snial, I've been missing this thread, feel free to ping my name so I get notified. This is what I get: I really did not have any problems compiling retro68k myself.
Thanks, it looks like the signature for your /opt/homebrew/lib/libboost_filesystem.dylib is the same as mine. Did you check that:

cat pathTo/Retro68-build/build-host/ResourceFiles/CMakeFiles/ResInfo.dir/link.txt

Says:

/usr/bin/c++ -Wall -Werror=return-type -Wno-multichar -g -arch arm64 -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/ResInfo.dir/ResInfo.cc.o -o ResInfo libResourceFiles.a /opt/homebrew/lib/libboost_program_options.dylib /opt/homebrew/lib/libboost_filesystem.dylib /opt/homebrew/lib/libboost_atomic.dylib /opt/homebrew/lib/libboost_system.dylib /Users/julianskidmore/Development/Retro68Dev/Retro68-build/toolchain/lib/libhfs.a

?

It could be one other cause - perhaps the source include paths are for x86_64 for me, so when libResourceFiles.a gets compiled, although the headers parse OK, they might generate different object code signatures.

I didn't read the whole thread in detail. I would recommend to wipe brew completely, delete your Retro68-build and redo it.
It's a bit drastic, but I might have to do that. I did find a while back that there was an Intel/Arm conflict with Brew and I thought I'd fixed that (it was compiling under Rosetta). However, I'm certainly able to compile things as ARM64 that use Brew libraries (e.g. Pce-mac).

I've learned a bit about the history of multiple architectures on Mac while delving into this. Pretty sure you know far more about that than me (@joevt must also be an expert I would have thought), but I'm kinda just discovering it. I knew that, obviously, code for 68K apps were stored in CODE resources in the resource fork of an app and when Apple shifted to PowerPC, code moved to the data fork and we could combine both to get fat binaries. This applied to libraries as well as applications.

But for the PowerPC to Intel transition it was different. We ended up with Universal binaries which could combine both PowerPC and Intel-32 object code and Apple added the lipo terminal command at that point so that they could be handled as single entities. So, I imagine that this caused some headaches during that Mac OS X transition.

But of course, it happened again in the transition to 64-bit: a new form of universal binary was needed, because essentially x86_64 is an incompatible instruction set (just like 32-bit x86 code was incompatible with 80286 and 8086 code). So lipo was needed again. And I guess, that because the 64-bit transition started in the PowerPC era, at some point it could have been possible to have libraries or executables (but not applications) which had 32-bit PowerPC code, 64-bit PowerPC code, 32-bit x86 code and 64-bit x64 code. Or maybe not special 64-bit PPC code given that the instruction set always supported 64-bit encodings?

Therefore it does make sense for Apple to sunset the previous generation. For example, 32-bit Windows 10 supported 16-bit Dos executables and 32-bit Windows executables. 64-bit Windows 10, didn't support 16-bit DOS executables, but did support 32-bit x86, 64-bit x86 and ARM64 executables; the same as Win 11 (AFAIK). But the whole separation of the OS into multiple SYSTEM, SYSTEM32 and Program Files, Program Files(64) and the ARM equivalent is a mess compared with the Apple approach in my opinion.

Therefore the pain may continue, though diminish until Intel support is fully retired, except for us retro users and developers!
 
And I guess, that because the 64-bit transition started in the PowerPC era, at some point it could have been possible to have libraries or executables (but not applications) which had 32-bit PowerPC code, 64-bit PowerPC code, 32-bit x86 code and 64-bit x64 code. Or maybe not special 64-bit PPC code given that the instruction set always supported 64-bit encodings?
Xcode for Mac OS X 10.6 can build for 32-bit and 64-bit ppc and intel:
Code:
% lipo -archs /Volumes/Work/Programming/pciutils/joevt-pciutils/build/build10.6/Debug/lspci 
x86_64 i386 ppc ppc64
ppc64 (G5) is separate from ppc (603-G3) so that you can use 64-bit optimizations. A utility like lspci doesn't need 64-bit optimizations but I built it that way to test the user client interface issues that occur with different architectures (same or different endian between kernel and user which happens with Rosetta) and bits (ppc kernel was never 64 bit but user apps could be 64 bit - Intel kernel can be 32 or 64 bit with 32 or 64 bit apps):

Code:
#=========================================================================================
# tested build10.6 DirectHW.kext

                        arch    darwin  darwin2 darwin3 intel-conf1     How to load unsigned DirectHW.kext
10.4.11 Tiger           p       -       -       p       -                
10.5.8  Leopard         pP      -       -       pP      -                
10.4.11 Tiger             i     i       -       p i     pi               
10.5.8  Leopard           ix    ix      -       p ix    pix              
10.6.8  Snow Leopard       x    ix      -       p ix    pix              
10.7.5  Lion               x    ix      -         ix     ix              
10.8.5  Mountain Lion      x    ix      -         ix     ix              
10.9.5  Mavericks          x    ix      -         ix     ix             install to /System/Library/Extensions.
10.10.5 Yosemite           x    ix      ix        ix     ix             add "kext-dev-mode=1" to boot-args.
10.11.6 El Capitan         x    -       -         ix     ix             disable SIP.
10.12.6 Sierra             x    -       panic     ix     ix             disable SIP.
10.13.6 High Sierra        x    ix      ix/panic  ix     ix             disable SIP.
10.14.6 Mojave             x    ix      ix        ix     ix             disable SIP.
10.15.7 Catalina           x     x       x         x      x             disable SIP.
11.7.2  Big Sur            x     x       x         x      x             disable SIP. Install to /Library/Extensions. Allow in "Security & Privacy" preferences panel. Restart.
12.6.2  Monterey           x     x       x         x      x             disable SIP. Install to /Library/Extensions. Allow in "Security & Privacy" preferences panel. Restart.
13.1    Ventura            x     x       x         x      x             disable SIP. Install to /Library/Extensions. Allow in "Security & Privacy" preferences panel. Restart.

                kernel          user
p = ppc         10.1            10.1
P = ppc64       -               10.5 SDK (only works on PPC Mac)
i = i386        10.4            10.4
x = x86_64      10.6            10.6
a = arm64       11              11

- for 10.1 to 10.3 : use GCC 3.3 and the oldest SDK.
- for 10.4 Xcode 2.2.x or 2.3, use GCC 4.0 and 10.4 SDK (not 10.4u).
- for 10.4 Xcode 2.4 or later, define KPI_10_4_0_PPC_COMPAT for PPC architecture, use 10.4u SDK for both PowerPC and Intel.
- for ppc64 user, 10.5 SDK has 64 bit libraries.

# darwin doesn't work from ppc userspace because AppleACPIPlatformExpert user client doesn't support cross endian.
# darwin doesn't work with ppc kernel since ppc doesn't have ACPI and doesn't use AppleACPIPlatformExpert.
# intel-conf1 method only supports registers 00-FF.
# both darwin3 and intel-conf1 require DirectHW.kext.
# darwin3 requires joevt/directhw.
# ppc userspace requires joevt/directhw.
# darwin and darwin2 require boot-args to contain "debug=".
# all require administrator rights.
# darwin2 requires OS X 10.10 or later.
# darwin2 panics in OS X 10.13 if boot-args does not contain "debug=".
# darwin and darwin2 don't seem to work in OS X 10.11; instead, use Darwin3 or intel-conf1 with DirectHW.kext.

Regarding retro68k, I haven't tried it yet. I might want to use it for compiling the ndrv for my emulated PCI graphics card for DingusPPC. I don't have an Apple Silicon Mac so I might not run into the same problems. I'm currently still using Monterey which Homebrew does not support but most of it still works (it may cause problems for me later).
 
@joevt , thanks for the informative reply!

@bribri , @Mu0n , @8bitbubsy , @MIST, @noglin. OK, I've made a bit more progress now in analysing the problem if not solving it. Going back to the error message I realised the problem isn't with ResInfo.cc.o , the newly compiled file that's being linked with the other libraries, but libResourceFiles.a , because that's what the error message actually says.

It turns out that nm's -C option demangles symbols; and if I ignore the -g option, I get the referenced symbols as well as the exported ones. So, here goes. lib expects:

$ nm libResourceFiles.a | grep "boost" | grep "append"
00000000000096e8 T __ZN5boost10filesystem4path9append_opC1ERS1_
000000000000971c T __ZN5boost10filesystem4path9append_opC2ERS1_
U __ZN5boost10filesystem4path9append_v3EPKcS3_


As I found out earlier, that's the version reported by the x86_64 architecture libboost_filesystem.dylib (which I extracted into a local BoostFs.dylib):

$ nm -gU BoostFs.dylib | grep "append"
000000000000fb40 T __ZN5boost10filesystem4path26append_separator_if_neededEv
000000000000f9d0 T __ZN5boost10filesystem4path9append_v3EPKcS3_
000000000000fee0 T __ZN5boost10filesystem4path9append_v4EPKcS3_


Whereas the arm64 one is:

$ nm -gU /opt/homebrew/lib/libboost_filesystem.dylib | grep "append"
000000000000f774 T __ZN5boost10filesystem6detail15path_algorithms26append_separator_if_neededERNS0_4pathE
0000000000010118 T __ZN5boost10filesystem6detail15path_algorithms9append_v3ERNS0_4pathEPKcS6_
0000000000010604 T __ZN5boost10filesystem6detail15path_algorithms9append_v4ERNS0_4pathEPKcS6_


And these are different signatures so it looks like libResourceFiles.a, which is arm64 is expecting a method defined in an x86_64 only library. But they're also mangled symbols- what if they're really the same underneath? We can use the -C option to work that out. It expects:

$ nm -C libResourceFiles.a | grep "boost" | grep "append_v3"
U boost::filesystem:: path::append_v3(char const*, char const*)

The x86_64 one is:

$ nm -gUC BoostFs.dylib | grep "append_v3"
000000000000f9d0 T boost::filesystem:: path::append_v3(char const*, char const*)


And the arm64 one is:

$ nm -gUC /opt/homebrew/lib/libboost_filesystem.dylib | grep "append_v3"
0000000000010118 T boost::filesystem::detail:: path_algorithms::append_v3(boost::filesystem:: path&, char const*, char const*)


So, now it's clear that there seems to be a difference between the append_v3 prototype for the arm64 library and the x86_64 one and the expects the x86_64 version. So, I would conclude it's a header problem. The Boost::... append_v3 prototype has changed, but the include file somehow references the old one and it's grabbing the include file from the wrong place, or the include files are in the wrong place.
 
@bribri , @Mu0n , @8bitbubsy , @MIST, @noglin. OK, I've made a bit more progress, I now know where the wrong prototype is coming from and why, but I don't yet know the best way to solve it.

To recap, the compilation fails, because libResourceFiles.a contains the x86_64 signature for boost::filesystem:: path::append_v3 instead of the arm64 signature, even though Retro68 knows it's compiling for arm64 and therefore when it (correctly) tries to link libResourceFiles.a with arm64 boost, it fails.

libResourceFiles.a is an archive generated from the .o files in ResourceFiles.dir. So, I used nm to scan through those and found that ResourceFile.cc.o was the only file which used append_v3 and unsurprisingly, it too, used the wrong one:

$ nm ResourceFile.cc.o | grep "boost" | grep "append"
00000000000096e8 T __ZN5boost10filesystem4path9append_opC1ERS1_
000000000000971c T __ZN5boost10filesystem4path9append_opC2ERS1_
U __ZN5boost10filesystem4path9append_v3EPKcS3_

$ nm -C ResourceFile.cc.o | grep "boost" | grep "append_v3"
U boost::filesystem:: path::append_v3(char const*, char const*)


I found that some of the CMake dependency stuff provided the include path to the proper version of the homebrew includes:

flags.make:CXX_INCLUDES = -I/Users/julianskidmore/Development/Retro68Dev/Retro68/ResourceFiles/. -I/Users/julianskidmore/Development/Retro68Dev/Retro68-build/toolchain/include -isystem /opt/homebrew/include

I found that /opt/homebrew/include/boost/filesystem/*.hpp contained the prototype I wanted:

$ grep "append_v3" /opt/homebrew/include/boost/filesystem/*.hpp
/opt/homebrew/include/boost/filesystem/path.hpp: BOOST_FILESYSTEM_DECL static void append_v3(path& p, const value_type* b, const value_type* e);


And that the other path, where I'd originally found the x86_64 boost.filesystem.dylib contained the wrong prototype for arm64:

$ grep "append_v3" /usr/local/include/boost/filesystem/*.hpp
/usr/local/include/boost/filesystem/path.hpp: BOOST_FILESYSTEM_DECL void append_v3(const value_type* b, const value_type* e);


So, now I know why it's using the wrong one: the INCLUDES contains -isystem so it finds the x86_64 include first.

I now have an idea of possible fixes:

  • Delete /usr/local/include/boost so that Retro68 only finds the homebrew version. This has the advantage that the boost include is only in one place.
  • Replace /usr/local/include/boost/* with /opt/homebrew/include/boost/*. This has the advantage that it'd be found correctly for arm64 builds just by searching for /usr/local/include/boost.
  • Replace /usr/local/include/boost/ with a link to /opt/homebrew/include/boost/. This has the advantage that it'd be found correct and there's still really only one location where the boost includes are.

The only fly in the ointment is this: conceivably, I could end up compiling something that really does need x86_64, because e.g. it links to a pre-built x86_64 library and also contains source code that uses boost. So, it wants to compile for x86_64 and therefore needs the x86_64 includes.

In the long-term that problem would go away along with x86_64 support, but in the meantime I think I want to keep my options open. One solution would be to modify the higher-level .hpp, which contains:

C:
//  boost/filesystem.hpp  --------------------------------------------------------------//

//  Copyright Beman Dawes 2010

//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt

//  Library home page: http://www.boost.org/libs/filesystem

//--------------------------------------------------------------------------------------//

#ifndef BOOST_FILESYSTEM_FILESYSTEM_HPP
#define BOOST_FILESYSTEM_FILESYSTEM_HPP

#include <boost/filesystem/config.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/exception.hpp>
#include <boost/filesystem/directory.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/file_status.hpp>
#include <boost/filesystem/convenience.hpp>
#if defined(BOOST_FILESYSTEM_DEPRECATED)
#include <boost/filesystem/string_file.hpp>
#endif

#endif // BOOST_FILESYSTEM_FILESYSTEM_HPP

So, that it checks for x86_64 (don't know how to do that yet) and simply #includes the combined filesystem.hpp from homebrew.

Or maybe there's a simpler solution, e.g. there's a newer x86_64 homebrew library for boost which has identical prototypes and .dylibs to arm64.

Still, I think I'm getting closer.
 
I would just delete boost and rebuild. Who knows how you got the x86-64 to begin with, by the time you would need it (if ever) things might have changed how they deal with this anyway.
 
I would just delete boost and rebuild. Who knows how you got the x86-64 to begin with, by the time you would need it (if ever) things might have changed how they deal with this anyway.
The reason why there are two different directories is because homebrew can't (or couldn't) build universal binaries. So, the Intel ones stay in /usr/local/[include], but the arm64 ones go in opt/homebrew/[include]. If you need both (or think you do), then the Intel directories ought to stay.


But following the actual Homebrew docs on it, they do say to uninstall the Intel stuff:

sudo /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)" -- --path=/usr/local
 
@bribri , @Mu0n , @8bitbubsy , @MIST, @noglin. OK! It looks like I'm there:

Done building Retro68.
The toolchain has been installed to: /Users/julianskidmore/Development/Retro68Dev/Retro68-build/toolchain/


I think I can try building the MOD player next!
I've been reading some of the documentation on building and running apps for Retro68 (ToughDev, Henlin's simplified guide), but again it seems to be a case of people not specifying critical information a newbie to CMake or Retro68 might not be aware of.

The bit I didn't understand is where I'm supposed to place the projects and then tell the project where the build environment was. I always thought it wouldn't be a good idea to place them in the actual Retro68-build directory, even though I think I could build the examples from there, because I always imagine that the installation directories should be left intact (e.g. if they were all installed on a read-only drive). I can see that if the CMake list uses relative directories, then it can all work OK, and maybe if I was a CMake expert I'd know it all. But if people don't, then guides shouldn't assume that.

Helpfully though... @MIST 's repo for NanoMac tracker does tell you in the .MD.

$ git clone https://github.com/harbaum/NanoMac.git
$ cd NanoMac/NanoMacTracker
$ ./bin2asm.py AXELF.MOD > AXELF.MOD.s #I had to find it in the .MOD archive, which @MIST links to.
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=/opt/Retro68/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake


Some cmake meta-building guff then followed. Note: I don't have Retro68 in /opt/Retro68, but in a subdirectory of my development stuff, so my path wasn't the same. Finally:

$ make

Builds the application and helpfully a .dsk image. I then ran miniVMac with my minimal System 3 disk and dragged the NanoMacTracker.dsk to the miniVMac window. Opening the disk and running the app gives me:

1754388931684.png
and it starts playing. It doesn't show the progress any more, but OTOH, I can click on [Quit] and it really will Quit, instead of hanging the Mac!

So, this means I've completed the first couple of steps in being able to support NanoMacTracker: I've installed Retro68 and proved I can build a 68K Mac application and run it on miniVMac. No debugging yet, but finally, real progress!

How long did this take? 9.5 days! The crucial information was the conflict between the #includes for Intel HomeBrew and arm64 HomeBrew, which was 'resolved' by uninstalling the Intel version. Though, I have a feeling if I need to create an x64 app under HomeBrew, I'll be faced with the reverse problem.
 
Back
Top