htacg / tidy-html5

The granddaddy of HTML tools, with support for modern standards
http://www.html-tidy.org
2.71k stars 414 forks source link

error: 'TARGET_OS_IOS' is not defined, evaluates to 0 [-Werror,-Wundef-prefix=TARGET_OS_] #1030

Open ryandesign opened 2 years ago

ryandesign commented 2 years ago

Software that includes tidy.h fails to compile on old OS versions like Mac OS X 10.6 when using a new compiler like clang 11:

In file included from /opt/local/include/tidy.h:69:
/opt/local/include/tidyplatform.h:118:9: error: 'TARGET_OS_IOS' is not defined, evaluates to 0 [-Werror,-Wundef-prefix=TARGET_OS_]
#    if TARGET_OS_IOS
        ^
1 error generated.

Here is a full build log.

The problem is that clang 11 now considers undefined TARGET_OS_* constants to be an error whereas previous versions of clang did not. tidyplatform.h checks various TARGET_OS_* constants which did not exist back when Mac OS X 10.6 was created and which are not defined in the Mac OS X 10.6 SDK's TargetConditionals.h:

#elif defined(__APPLE__) && defined(__MACH__)
    /* Mac OS X (client) 10.x (or server 1.x/10.x) - gcc or Metrowerks MachO compilers */
#  define MAC_OS_X
#  ifndef PLATFORM_NAME
#    include "TargetConditionals.h"
#    if TARGET_OS_IOS
#      define PLATFORM_NAME "Apple iOS"
#    elif TARGET_OS_MAC
#      define PLATFORM_NAME "Apple macOS"
#    elif TARGET_OS_TV
#      define PLATFORM_NAME "Apple tvOS"
#    elif TARGET_OS_WATCH
#      define PLATFORM_NAME "Apple watchOS"
#    else
#      define PLATFORM_NAME "Apple Unknown OS"
#    endif
#  endif
#endif

I don't know why you need to define a PLATFORM_NAME, but if you do, I suggest you check if a constant is defined before you check its value to avoid the error, e.g.:

#    if defined(TARGET_OS_IOS) && TARGET_OS_IOS

You're also using TARGET_OS_MAC wrong. TARGET_OS_MAC means any Apple Darwin-based operating system, including macOS, iOS, iPadOS, tvOS, watchOS. The macOS 11.1 SDK's TargetConditionals.h contains this explanation of the various constants:

 *      TARGET_OS_WIN32           - Generated code will run under 32-bit Windows
 *      TARGET_OS_UNIX            - Generated code will run under some Unix (not OSX)
 *      TARGET_OS_MAC             - Generated code will run under Mac OS X variant
 *         TARGET_OS_OSX          - Generated code will run under OS X devices
 *         TARGET_OS_IPHONE          - Generated code for firmware, devices, or simulator
 *            TARGET_OS_IOS             - Generated code will run under iOS
 *            TARGET_OS_TV              - Generated code will run under Apple TV OS
 *            TARGET_OS_WATCH           - Generated code will run under Apple Watch OS
 *            TARGET_OS_BRIDGE          - Generated code will run under Bridge devices
 *            TARGET_OS_MACCATALYST     - Generated code will run under macOS
 *         TARGET_OS_SIMULATOR      - Generated code will run under a simulator
 *
 *      TARGET_OS_EMBEDDED        - DEPRECATED: Use TARGET_OS_IPHONE and/or TARGET_OS_SIMULATOR instead
 *      TARGET_IPHONE_SIMULATOR   - DEPRECATED: Same as TARGET_OS_SIMULATOR
 *      TARGET_OS_NANO            - DEPRECATED: Same as TARGET_OS_WATCH
 *
 *    +---------------------------------------------------------------------+
 *    |                            TARGET_OS_MAC                            |
 *    | +---+ +-----------------------------------------------+ +---------+ |
 *    | |   | |               TARGET_OS_IPHONE                | |         | |
 *    | |   | | +---------------+ +----+ +-------+ +--------+ | |         | |
 *    | |   | | |      IOS      | |    | |       | |        | | |         | |
 *    | |OSX| | |+-------------+| | TV | | WATCH | | BRIDGE | | |DRIVERKIT| |
 *    | |   | | || MACCATALYST || |    | |       | |        | | |         | |
 *    | |   | | |+-------------+| |    | |       | |        | | |         | |
 *    | |   | | +---------------+ +----+ +-------+ +--------+ | |         | |
 *    | +---+ +-----------------------------------------------+ +---------+ |
 *    +---------------------------------------------------------------------+

So if you want to know specifically if you're on macOS, you could check TARGET_OS_OSX, except that again that constant does not exist on Mac OS X 10.6. So my suggestion would be to check for iOS and tvOS and watchOS and if it's none of those then it's macOS. I suppose it is unlikely that tidy would ever be running under bridgeOS so you may not need to bother checking that.

ryandesign commented 2 years ago

In the 10.6 SDK, TargetConditionals.h defined fewer constants:

    TARGET_OS_* 
    These conditionals specify in which Operating System the generated code will
    run. The MAC/WIN32/UNIX conditionals are mutually exclusive.  The EMBEDDED/IPHONE 
    conditionals are variants of TARGET_OS_MAC. 

        TARGET_OS_MAC           - Generate code will run under Mac OS
        TARGET_OS_WIN32         - Generate code will run under 32-bit Windows
        TARGET_OS_UNIX          - Generate code will run under some non Mac OS X unix 
        TARGET_OS_EMBEDDED      - Generate code will run under an embedded OS variant
                                  of TARGET_OS_MAC
        TARGET_OS_IPHONE        - Generate code will run under iPhone OS which 
                                  is a variant of TARGET_OS_MAC.

With all this in mind, here's one possible solution:

https://github.com/macports/macports-ports/blob/60164e3fd3f8d006b408a4a58349f7e17b54e26d/www/tidy/files/tidyplatform.h.patch