fprintf, NSLog, os_log and OutputDebugString

I am a bit at loss when a Cocoa plugin is not compiled as OBJC. On Sierra (10.12xx) you can use os_log to get messages out to the Console.app, while fprintf, using stderr sends messages to Terminal.app on windows and Mac (Linux too, but is not relevant in this context). On windows, sending messages to DebugView when using OutputDebugString. On older OS X versions we could use DebugStr, but does not seem to work on OS X 10.9, 10.10 and 10.11. The plugin cannot be compiled as Objective-C, so NSLog is out of the question.

If there is a solution for 10.9/10.10/10.11 I would appreciate to hear about it. In addition, how should one include <OS/log.h> at runtime, which depends on whether or not we are running 10.12?

DebugStr has been deprecated for a very, very long time and I have no idea when it last actually did something. You could use asl_log.

Weakly linking against os_log would be done by building against the 10.12 SDK with a deployment target set to your oldest target. Normally you’d just need to test the function against NULL, but os_log is a macro and you’d need to check against _os_log_internal.

You can use NSLog. Just declare it with CFStringRef yourself.

That’s it. Cool. I was not aware of asl_log.

#ifdef WIN32
    #include <OS/log.h>
    #include <asl.h>

#define TRACE

#ifdef TRACE
void ScriptDebugDisplay(const char *s)
#ifdef WIN32
    fprintf( stderr, "%s\
", s );
    fprintf( stderr, "%s", s ); // not seen in console, but seen in terminal
    if (_os_log_internal == NULL) {
        /*! @header
         * These routines are deprecated and replaced by os_log(3).  On OS versions
         * with os_log(3), the ASL routines for emitting log messages are shimmed into
         * the equivalent os_log functionality.  Functions whose deprecation messages
         * indicate they are unsupported will have no effect on OS versions with
         * os_log(3) support.
        aslmsg msg = asl_new(ASL_TYPE_MSG);
        asl_set(msg, ASL_KEY_READ_UID, "-1");
        asl_log(NULL, msg, ASL_LEVEL_NOTICE, "%s", s);
    } else {
        os_log(OS_LOG_DEFAULT, "%{public}s", s); // seen in console using desktop

Many thanks.