Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build fails with libjpeg-turbo 3.0.3: Undefined symbols for architecture x86_64: "_jpeg_std_message_table" #7074

Closed
barracuda156 opened this issue May 13, 2024 · 12 comments · Fixed by #7080
Labels
priority: high Should be fixed with higher urgency
Milestone

Comments

@barracuda156
Copy link

Looks that libjpeg-turgo changed API in 3.0.3, and this code now does not work:

#ifdef _WIN32
#define JVERSION "6b 27-Mar-1998"
#define JCOPYRIGHT_SHORT "(C) 1998, Thomas G. Lane"
#define JMESSAGE(code,string) string ,
const char * const jpeg_std_message_table[] = {
#include "jerror.h"
NULL
};
#else
extern const char * const jpeg_std_message_table[];
#endif

Windows build has this issue years ago: #4713
Now identical linking failure on macOS: https://build.macports.org/builders/ports-14_x86_64-builder/builds/39199/steps/install-port/logs/stdio

This compiles though:

const char * const jpeg_std_message_table[] = {
#include "jerror.h"
  NULL
};

(Functionality not tested.)

@barracuda156
Copy link
Author

Builds fine against 3.0.2, confirmed. So definitely libjpeg-turbo issue.

@ryandesign
Copy link

libjpeg-turbo says it is a RawTherapee issue; see libjpeg-turbo/libjpeg-turbo#763

@dcommander
Copy link

libjpeg-turbo did not change its API. jpeg_std_message_table[] was never a part of any API, either public or private. It is a local symbol in jerror.c, and its exposure at the global level was only accidental and only on certain platforms. Our Un*x shared library uses a linker script to determine symbol exposure, so I posit that RawTherapee's approach could not have worked with that library. (In other words, your approach was not cross-platform.)

tl;dr: Your software relies on accidental, undocumented, unofficial behavior that only occurred on certain platforms, so you can't complain about that behavior changing. There is almost certainly a better way to accomplish what you're trying to accomplish than to needlessly duplicate a lot of the internals of libjpeg-turbo.

@dcommander
Copy link

Note that, when you call jpeg_std_error(), a pointer to jpeg_std_message_table[] is returned in err->jpeg_message_table. That is the correct way to access jpeg_std_message_table[]. After calling jpeg_std_error(), your code can then override the error_exit(), emit_message(), output_message(), format_message(), or reset_error_mgr() methods if necessary.

@barracuda156
Copy link
Author

@dcommander Just to be clear, this is not my software, we did not add this part in MacPorts, we just got a sudden breakage upon libjpeg-turbo update.

@dcommander
Copy link

@dcommander Just to be clear, this is not my software, we did not add this part in MacPorts, we just got a sudden breakage upon libjpeg-turbo update.

Yes, you've already mentioned that. But this issue is under the RawTherapee project, so "your" refers to the RawTherapee authors.

@Benitoite
Copy link
Contributor

Currently RT builds on Mac ARM but only with libjpeg-turbo downgraded to 3.0.2
libjpeg-turbo/libjpeg-turbo#763 (comment) says RT was/is using an unexposed call of some sort.

@kmilos
Copy link
Contributor

kmilos commented May 17, 2024

Note that MSYS2 libjpeg-turbo just got bumped to 3.0.3.

@Benitoite
Copy link
Contributor

I found a patch written for this bug: termux-user-repository/tur#1027

@Lawrence37
Copy link
Collaborator

Thank you @Benitoite! I will have a look at your pull request.

@Lawrence37 Lawrence37 added this to the v5.11 milestone May 19, 2024
@Lawrence37 Lawrence37 added the priority: high Should be fixed with higher urgency label May 19, 2024
@haplo
Copy link

haplo commented May 22, 2024

Will there be a minor release (5.10.1) that includes a fix for this bug, or will it wait until 5.11?

I ask because RawTherapee is currently broken on Arch Linux, and depending on the expected time for a fixed release I would consider opening an issue with them to include this patch temporarily.

Thank you for your support!

@haplo
Copy link

haplo commented May 23, 2024

Nevermind, Arch Linux just released a new version with the jpeg-turbo patch:

https://gitlab.archlinux.org/archlinux/packaging/packages/rawtherapee/-/commit/ca57665a9b247386c78a46585ca977370396133f

dcommander added a commit to libjpeg-turbo/libjpeg-turbo that referenced this issue May 29, 2024
jpeg_std_message_table[] was never a documented part of the libjpeg API,
nor was it exposed in jpegint.h or the Windows libjpeg API DLL.  Thus,
it was never a good idea (nor was it even remotely necessary) for
applications to use it.  However, referring to #763 and #767, one
application (RawTherapee) did use it.
34c0558 hid the symbol, which broke the
Un*x builds of RawTherapee.  (RawTherapee already did the right thing on
Windows, because jpeg_std_message_table[] was not exposed in the
Windows libjpeg API DLL.  Referring to
Beep6581/RawTherapee#7074, RawTherapee now
does the right thing on Un*x platforms as well.)

The comment in jerror.c indicated that Tom Lane intended the symbol to
be external "just in case any applications want to refer to it
directly."  However, with respect to libjpeg-turbo, the comment was
effectively already a lie on Windows.  My choices at this point are:

1. Revert 34c0558 and start exposing
   the symbol on Windows, thus making the comment true again.
2. Remove the comment.

Option 1 would have created whiplash, since 3.0.3 has already been
released with the symbol hidden, and that option would have further
encouraged ill-advised behavior on the part of applications.  Since the
issue has already been fixed in RawTherapee, and since it is known to
affect only that application, I chose Option 2.

In my professional opinion, a code comment does not rise to the level
of a contract between a library and a calling application.  In other
words, the comment did not make the symbol part of the API, even though
the symbol was exposed on some platforms.  Applications that use
internal symbols (even the symbols defined in jpegint.h) do so at their
own risk.  There is no guarantee that those symbols will remain
unchanged from release to release, as it is sometimes necessary to
modify the internal (opaque) structures and methods in order to
implement new features or even fix bugs.  Some implementations of the
libjpeg API (such as the one in Jpegli, for instance), do not provide
those internal symbols at all.  Best practices are for applications that
use the internal libjpeg-turbo symbols to provide their own copy of
libjpeg-turbo (for instance, via static linking), so they can manage any
unexpected changes in those symbols.  (In fact, that is how libjpeg was
originally used.  Application developers built it from source with
compile-time options to exclude unneeded functionality.  Thus, no two
builds of libjpeg were guaranteed to be API/ABI-compatible.  The idea of
a libjpeg shared library that exposes a pseudo-standard ABI came later,
and that has always been an awkward fit for an API that was intended to
be modified at compile time to suit specific application needs.
libjpeg-turbo's colorspace extensions are but one example, among many,
of our attempts to reconcile that awkwardness while preserving backward
compatibility with the aforementioned pseudo-standard ABI.)
dcommander added a commit to libjpeg-turbo/libjpeg-turbo that referenced this issue May 29, 2024
jpeg_std_message_table[] was never a documented part of the libjpeg API,
nor was it exposed in jpegint.h or the Windows libjpeg API DLL.  Thus,
it was never a good idea (nor was it even remotely necessary) for
applications to use it.  However, referring to #763 and #767, one
application (RawTherapee) did use it.
34c0558 hid the symbol, which broke the
Un*x builds of RawTherapee.  (RawTherapee already did the right thing on
Windows, because jpeg_std_message_table[] was not exposed in the
Windows libjpeg API DLL.  Referring to
Beep6581/RawTherapee#7074, RawTherapee now
does the right thing on Un*x platforms as well.)

The comment in jerror.c indicated that Tom Lane intended the symbol to
be external "just in case any applications want to refer to it
directly."  However, with respect to libjpeg-turbo, the comment was
effectively already a lie on Windows.  My choices at this point are:

1. Revert 34c0558 and start exposing
   the symbol on Windows, thus making the comment true again.
2. Remove the comment.

Option 1 would have created whiplash, since 3.0.3 has already been
released with the symbol hidden, and that option would have further
encouraged ill-advised behavior on the part of applications.  Since the
issue has already been fixed in RawTherapee, and since it is known to
affect only that application, I chose Option 2.

In my professional opinion, a code comment does not rise to the level
of a contract between a library and a calling application.  In other
words, the comment did not make the symbol part of the API, even though
the symbol was exposed on some platforms.  Applications that use
internal symbols (even the symbols defined in jpegint.h) do so at their
own risk.  There is no guarantee that those symbols will remain
unchanged from release to release, as it is sometimes necessary to
modify the internal (opaque) structures and methods in order to
implement new features or even fix bugs.  Some implementations of the
libjpeg API (such as the one in Jpegli, for instance), do not provide
those internal symbols at all.  Best practices are for applications that
use the internal libjpeg-turbo symbols to provide their own copy of
libjpeg-turbo (for instance, via static linking), so they can manage any
unexpected changes in those symbols.  (In fact, that is how libjpeg was
originally used.  Application developers built it from source with
compile-time options to exclude unneeded functionality.  Thus, no two
builds of libjpeg were guaranteed to be API/ABI-compatible.  The idea of
a libjpeg shared library that exposes a pseudo-standard ABI came later,
and that has always been an awkward fit for an API that was intended to
be modified at compile time to suit specific application needs.
libjpeg-turbo's colorspace extensions are but one example, among many,
of our attempts to reconcile that awkwardness while preserving backward
compatibility with the aforementioned pseudo-standard ABI.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: high Should be fixed with higher urgency
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants