Some languages have tools and features that make cross-compilation less painful. For example, Rust offers cross-compilation as a semi-native functionality in its toolchain. But you’ll still need to bring in some other bits to complete the experience – like the right linker.
One big problem with cross-platform compilation is how asymmetrical can be. If you’re a macOS user, it’s easy to set up and maintain Windows or Linux virtual machines on your Mac. If you’re using Linux or Windows, it’s harder to emulate macOS on those platforms. No impossibleonly more difficult – the biggest reason being legal issues, as the macOS EULA doesn’t allow it to be used on non-Apple hardware. The easiest solution (though hardly the cheapest) is to simply buy a standalone Macintosh system and use that. Another option is to use tools like osxcross to cross compile on Linux, FreeBSD, or OpenBSD.
Another common option that is most in line with modern software delivery methods is to use a system like GitHub Actions (via runners hosted on GitHub) or Azure Pipelines to build software on any of their supported target platforms. (MacOS supports both GitHub and Azure.) The downside is paying to use the service, but if you’re already invested in one of the platforms, this is often the most economical and least complicated approach. In addition, it will make it impossible for you to maintain the system.