On Dec 6, 2021, at 22:55, Bruno Haible wrote: > > Hi Ryan, > > Ryan Schmidt wrote: >> Hi, gnulib fails to build on Mac OS X 10.4 Tiger: >> >> get_ppid_of.c:36:22: error: libproc.h: No such file or directory >> >> libproc.h was introduced in Mac OS X 10.5 Leopard. > > The Gnulib module 'sigsegv' is another module which supports Mac OS X 10.5 > nicely but not Mac OS X 10.4. > > More generally, how do you — in MacPorts — handle the case of a functionality > that is available in Mac OS X versions >= V, but not in versions < V? (I'm > asking you because normal macOS users typically build binaries just for their > particular OS version.) > > Do you have a mechanism for building separate binaries for ≥ V and < V? > > Do you attempt to build the code for ≥ V, even though it won't work for < V? > > Do you use a replacement for the versions < V, and a version test at runtime > (and, if so, how do you code this version test)? > > Do you have a timeline when you will drop support for Mac OS X 10.4?
Hi Bruce, The MacPorts base system (i.e. the `port' command) requires Mac OS X 10.4 or later. MacPorts base doesn't use a lot of Mac-specific functionality so nothing has come up yet that would require us to drop support for that version. The thousands of individual ports that can be installed with MacPorts each have different requirements, and a large number of them surely don't build on 10.4 anymore since it is so old, but some ports still do, and we do still have a few users who like using MacPorts to install software on their old PowerPC Macs, some of which can't officially be upgraded past 10.4 and none of which can be upgraded past 10.5. macOS has a mechanism for allowing software to be built on newer OS versions but such that it can still be run on older OS versions: the MACOSX_DEPLOYMENT_TARGET environment variable or equivalently the -mmacosx-version-min compiler flag. The way that Apple intends this to be used is that a developer will use the most recent macOS and OS SDK on their compilation and development computer, and then specify which minimum OS version they require users to have. Any symbols available in the minimum desired OS version will be linked normally (guaranteed to be available at runtime) while any symbols available only in newer systems will be weak-linked; it is the responsibility of the application or library developer to know that this might happen, and to have the software check at runtime whether such symbols exist, and to only use the functionality at runtime if it exists. Because many open source projects are written by developers not aware of these Mac-specific features, MacPorts doesn't normally rely on this. MacPorts normally sets the deployment target to be the same as the running OS version, and ports are built on the same OS version on which they will be used. We have separate build machines for each major OS version (in some cases two, for situations where the OS is available on multiple processor architectures) and when a user installs a port, MacPorts first tries to download a binary built for and on that OS version, and if that fails, then it compiles from source on the user's machine. But if you are developing a portable library, you would want to support compiling for an earlier macOS than the one you're compiling on. The problem with Apple's suggested approach is that while it works great for the developer who compiles and releases binaries, it works less well for open source software where users want to compile the software, if the user doesn't have the latest OS or OS SDK. Supposing that libproc.h declares functions you want to call that are available on 10.5 but not 10.4, and that this functionality is optional and you can code around its absence, you could modify gnulib so that it checks at runtime and only calls those functions if they exist. That would help someone who is on 10.4 using a gnulib that was built on 10.5 using deployment target 10.4, but it doesn't help someone trying to build on 10.4 because 10.4 doesn't have libproc.h and the 10.5 SDK isn't available in any Xcode version that's compatible with 10.4. To solve that problem, in addition to the preceding about checking for weak-linked symbols, you can use preprocessor defines within the source code, and only include libproc.h and only compile the code that uses its functions if your SDK is 10.5 or greater. The relevant defines are MAC_OS_X_VERSION_MAX_ALLOWED and MAC_OS_X_VERSION_MIN_REQUIRED. MAC_OS_X_VERSION_MAX_ALLOWED refers to the SDK version. For example to include libproc.h only if you are compiling with the 10.5 SDK or later: #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 #include <libproc.h> #endif MAC_OS_X_VERSION_MIN_REQUIRED refers to the deployment target. If you want to know that your code is guaranteed to be running on 10.5 or later: #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 You might use this, for example, to write more efficient code: If you're deploying for 10.5 or later, then those symbols only available in 10.5 or later will be normally linked, not weak linked, so you don't need to check if they exist; you already know they do. For those two defines to exist, you have to include AvailabilityMacros.h, which you should do only on Apple platforms: #ifdef __APPLE__ #include <AvailabilityMacros.h> #endif In 10.5, Apple introduced a new header Availability.h which they want you to use instead of AvailabilityMacros.h, but since the goal here is to support 10.4, which doesn't have that header, you'd have to keep using AvailabilityMacros.h. A MacPorts user running Mac OS X 10.4 proposed this fix which just hides the #include of <libproc.h> and its uses behind the 10.5 deployment target check, without attempting to provide any alternative when deploying for earlier versions nor attempting to allow libproc features to be used if running on 10.5 or greater when compiled for 10.4. I commented that I did not know whether this fix was correct and asked them to bring it up on this list, but since I don't think they have, I'm bringing it up for them. https://github.com/macports/macports-ports/pull/13226/files#diff-8a2ad00cea356fb07a25e323fde8a18232252de4f6421d5e73347aa845d56045 (They used __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ instead of MAC_OS_X_VERSION_MIN_REQUIRED; the distinction is not clear to me. It might be that __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ is defined even if AvailabilityMacros.h is not included.) We may also need to think about what happens when compiling for a non-macOS Apple OS (iOS, iPadOS, tvOS, watchOS). I don't think *MAC_OS_X* defines will be defined on those other OSes. In MacPorts we don't try to solve the problem since we only compile for macOS.