Hi, As we try to build Ghostscript (checked with 9.53.0 and 9.52 versions) with THREADSAFE parameter, using Visual Studio 2019 over Windows 10, build process returns an error: Error LNK2019 unresolved external symbol errprintf_nomem referenced in function gs_log_error Error is located in mkromfs.c file, which has a method called errprintf_nomem that can't be found when GS_TRHEADSAFE is set. To give some context: We see from doc\History9.htm: ------------------------------------ 2019-05-29 15:56:20 -0700 Ray Johnston <ray.johnston@artifex.com> {650c49424529fca922519ee9cdf2086eee5cfb70} Fix broken DEBUG build. Add standalone gs_log_error to mkromfs.c This function is invoked for DEBUG builds by gs_note_error. We define an equivalent local version so we don't have to include gsmisc.obj (as for other utility functions such as outprintf). base/mkromfs.c ------------------------------------ So, taking a look at mkromfs.c file (were exception raises on compiling): int gs_log_error(int err, const char *file, int line) { if (file == NULL) errprintf_nomem("Returning error %d.\n", err); else errprintf_nomem("%s(%d): Returning error %d.\n", (const char *)file, line, err); return err; } It always calls to errprintf_nomem function. Looking for its definition on same file: #ifndef GS_THREADSAFE int errprintf_nomem(const char *fmt, ...) { int count; char buf[PRINTF_BUF_LENGTH]; va_list args; va_start(args, fmt); count = vsnprintf(buf, sizeof(buf), fmt, args); if (count < 0 || count >= sizeof(buf)) { /* MSVC || C99 */ fwrite(buf, 1, sizeof(buf) - 1, stderr); fwrite(msg_truncated, 1, sizeof(msg_truncated) - 1, stderr); } else { fwrite(buf, 1, count, stderr); } va_end(args); return count; } #endif So, errprintf_nomem won't be present when compiling using GS_THREADSAFE flag, even it is referenced by gs_log_error which was introduced as standalone function on 2019-05-29, as referenced on History9.htm file. I guess there should be an alternative definition for the local defined gs_log_error in case GS_THREADSAFE is present. Note: To compile with THREADSAFE capability, we simple use this sentence on "Rebuild all" option: cd .. && nmake -f psi\msvc32.mak WIN64= SBR=1 DEVSTUDIO= XCFLAGS=-DGS_THREADSAFE=1 && nmake -f psi\msvc32.mak WIN64= DEVSTUDIO= XCFLAGS=-DGS_THREADSAFE=1 bsc Thanks in advace.
Created attachment 19841 [details] Patch There are several ways to fix this: Since local versions of errprintf_nomem() and errprintf() are mostly identical, one can just call errprintf() with a dummy mem argument. This approach is implemented in the attached patch. One can also keep errprintf_nomem() in all cases, because mkromfs does not need thread safety, and the local version of errprintf_nomem() is thread safe anyway. It is also possible to use call fprintf(stderr, ...) directly in mkromfs and reduce the level of indirection and confusion even more.
Sorry, Chris. BTW, I can force this same error on linux (so Chris doesn't have to mess with linux) using: make XCFLAGSAUX=-DGS_THREADSAFE
Slightly tweaked patch applied in: https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=0ca4ae94020a Thanks