transcode 1.0.5 invalid immediate error on Intel OS X

If you’re compiling transcode 1.0.5 from source on OS X Intel (for some odd reason, as I’ve just had to do on 10.5.4), your compile run may blow up in aclib with:


tcmemcpy.c:30:missing or invalid immediate expression `0b111' taken as 0
tcmemcpy.c:30:suffix or operands invalid for `and'
tcmemcpy.c:42:missing or invalid immediate expression `0b1000' taken as 0
tcmemcpy.c:42:suffix or operands invalid for `test'
tcmemcpy.c:52:missing or invalid immediate expression `0b1111' taken as 0

The problem here appears to be that the code in tcmemcpy.c under x86 and x86_64 relies on some inline assembly features not supported by all compiler/assemblers. Namely, the use of 0b (binary immediate) operands in assembly instructions is not apparently supported during compilation under Apple gcc and gcc-4.2.

Setting the CCAS flag did not seem to help. A quick fix, then, is to convert all binary immediates in the asm instructions to hex or decimal.

Thankfully, these operands only existed in tcmemcpy, so there’s not too much work. Look for 0bxxxx immediates and convert them to their hex or decimal equivalent. For example, 0b111 is 0x7, 0b1000 is 0x8, 0b1111 is 0xf. Thus, a line like:
and $0b111, %%eax # ... which is the number of bytes to copyn

becomes
and $0x7, %%eax # ... which is the number of bytes to copyn

Once these operands are modified, the compiler should no longer complain about invalid immediate expressions.

In any case, the latest CVS version of transcode should have resolved these problems already. The workaround should only be necessary if you still must compile the release tarball for 1.0.5.

Updated: There is a second potential problem if you were using ffmpeg-SVN and transcode 1.0.5, in which its hard-coded include lookup for avcodec.h always looks for ffmpeg/avcodec.h. The SVN version of ffmpeg has moved these headers to libavcodec/avcodec.h. A path patch for transcode 1.0.5 and ffmpeg is available, which basically boils down to changing the #include headers and the configure.in file to look for the new path.

Updated: A third problem has now cropped up, with the ffmpeg API change that moved AVCodecContext’s bits_per_sample to bits_per_coded_sample. A global search and replace seems to work for now. See this also in my post on compiling Perian.

transcode compile error – preprocessor macros vs attributes

Had a problem compiling transcode 1.0.4 on my OS X Tiger (PPC).

In file included from /usr/include/math.h:26,
from pvnglobals.h:26,
from pvn.h:15,
from import_pvn.c:39:
/usr/include/architecture/ppc/math.h:179: error: parse error before '__attribute__'
/usr/include/architecture/ppc/math.h:179: error: parse error before 'inline'
/usr/include/architecture/ppc/math.h:180: error: parse error before '__attribute__'
/usr/include/architecture/ppc/math.h:180: error: parse error before 'inline'

… and so forth. The whole math.h business is a red herring; or rather, it’s a symptom, not the cause.

The issue appears to stem from a preprocessor macro problem in src/transcode.h. Around line 85 or so, find the block

#ifndef always_inline
#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
# define always_inline __attribute__((always_inline)) inline
#else
# define always_inline inline
#endif
#endif

A rather odd and potentially problematic thing to do, because now in math.h:83, we note:

#define __MATH_H_ALWAYS_INLINE__ __attribute__ ((always_inline))

which later gets used in math.h:179, 180, and so forth.

Now, because of the first #define, it seems we’re likely to cause __MATH_H_ALWAYS_INLINE__ to become something like __attribute__((__attribute__ ((always_inline)) inline)). Unlikely to compile cleanly.

One possible solution is to swap around the header orders so that math.h is included before transcode.h clobbers the always_inline definition.

Another workaround: comment out in the inner #if and preserve only the else-branch in transcode.h:

#ifndef always_inline
# define always_inline inline
#endif

It fixes the compilation problem, presumably because it no longer causes the always_inline definition to conflict with the one in math.h. Unfortunately, it also changes the meaning of __attribute__ ((always_inline)) in math.h. The first solution is preferable, even though it might be more tedious to trace the include blowups that result.

The moral of the story is that it’s usually bad to screw with built-in keywords via preprocessor macros.