Opened 8 years ago

Closed 8 years ago

#14144 closed defect (fixed)

-framework QuickTime should not be included

Reported by: mojca Owned by:
Priority: low Milestone:
Component: wxOSX Version: 2.9.3
Keywords: configure, Mac OS X, QuickTime Cc:
Blocked By: Blocking:
Patch: no

Description

When I build projects with wxWidgets 2.9.3 on Mac OS X Lion I get the following warning:

ld: warning: ignoring file /System/Library/Frameworks/QuickTime.framework/QuickTime, file was built for unsupported file format which is not the architecture being linked (x86_64)

The problem is that (on MacPorts) the file /opt/local/bin/wx-config contains

echo $_ldflags "  -framework IOKit -framework Carbon -framework Cocoa -framework AudioToolbox -framework System -framework OpenGL -framework QuickTime" $_rpath $wx_libs ""

I'm not exactly sure where this line originates since it is present in build/osx/wxcocoa.xcconfig, twice in configure and twice in configure.in, but it would be great if this could be fixed in one way or another.

wxWidgets also cannot be built with clang++, but that is a completely different issue anyway.

Attachments (1)

configure_in_quicktime.diff download (1.4 KB) - added by mojca 8 years ago.
Patch that removes -framework QuickTime on Mac when building only for x86_64

Download all attachments as: .zip

Change History (19)

comment:1 Changed 8 years ago by vadz

  • Priority changed from normal to low
  • Status changed from new to confirmed

The problem is that we do need QuickTime in 32 bits and it's only in 64 bits that it's neither available nor needed. Currently the flags we use are the same for both cases however so we'd need to modify configure to do it differently depending on the bitness of the build and I'm not sure what is the right way to test for 32 bit only (and not fat 32/64 bit one).

Finally, this won't solve the problem for fat 32/64 bit builds anyhow, of course, as we'll need to continue including this framework there and it still will result in warnings. So AFAICS we'll just have to continue to live with this for now.

comment:2 Changed 8 years ago by mojca

Based on what you told me, here is one example that could work:

if test "x$wxUSE_UNIVERSAL_BINARY" = "xyes"; then
	EXTRA_FRAMEWORKS="$EXTRA_FRAMEWORKS -framework QuickTime"
else
	case "$wxUSE_MAC_ARCH" in
		x86_64) ;; # don't use QuickTime
		no) # test if we are building 64-bit machine
			if test `uname -m` != "x86_64"; then
				EXTRA_FRAMEWORKS="$EXTRA_FRAMEWORKS -framework QuickTime"
			fi ;;
		*) # i386|ppc
			EXTRA_FRAMEWORKS="$EXTRA_FRAMEWORKS -framework QuickTime";;
	esac
fi

The only problem is that "uname -m" is not a 100% reliable test of what architecture we are building on. The proper way to do it would be compiling a simple int main() { return 0; } with the chosen compiler and compiler flags, run "file" on resulting binary and check if this builds i386/ppc. (This test would also replace the whole code that I wrote above.)

Cases where my code could go wrong: user explicitly sets "CXX=i686-apple-darwin11-g++-4.2.1" or "CXXFLAGS=-arch i386", or machine reports i386 when it actually uses 64-bit compiler. This can be checked with

if test `sysctl -n hw.cpu64bit_capable` = 1; then

but simply running the compiler and checking the result should be easier and more reliable.

comment:3 Changed 8 years ago by mojca

I forgot to say that my code above checks if user has specified one of the following flags:

--enable-universal_binary  create universal binary with Mac PPC and i386 (and x86_64 if using Cocoa) architectures
--enable-macosx_arch=ARCH  build for just the specified architecture

But then again I don't 100% understand and comprehend all the zillions of possible combinations of using a different compiler for compiling wxWidgets themselves and for compiling programs using wxWidgets.

comment:4 Changed 8 years ago by vadz

It's not a problem to check if we're building in 64 bits, we can compile a test program to determine it (but examining the system CPU doesn't help at all because you can perfectly well build in 32 bits on a 64 bit CPU).

But I still don't see how would doing it help at all with universal builds as the same wx-config is used for both 32 and 64 bit setting and it needs to output -framework QuickTime for the former but not the latter. Do you see the problem?

comment:5 Changed 8 years ago by mojca

Yes, I see the problem, but when doing an universal build, there is simply NO way around it (except for running the compiler twice and using lipo to merge results; and going that way is not worth the time it takes to do it). The command

gcc -arch i386 -arch x86_64 -framework QuickTime hello.c 

will simply always end up with that warning. But in my opinion it would still make sense to get rid of the warning for those who don't need i386 code and there will be an increasing percentage of such users with time.

So: may I request removing the QuickTime flag "if and only if" user is building for x86_64 only? I know that some will still experience the problems, but for others it will go away at least.

comment:6 Changed 8 years ago by vadz

OK, my impression was that most people would be using universal builds but you're right, it's still better to avoid it at least for those building 64 bit code only.

To check for 64 bit build we can use test "$ac_cv_sizeof_long" = 8 but we also need to check that we're building for a single arch only which, AFAICS, can be done by just test "x$wxUSE_UNIVERSAL_BINARY" != xno (this would result in false positives for "--enable-universal_binary=x86_64" but this is just stupid anyhow, so it's OK).

Could you please make a patch (to configure.in only, no need to submit the modified configure itself) and test it?

TIA!

comment:7 Changed 8 years ago by mojca

Just a question (since I'm a bit inexperienced in autotools). What about users who configure wxwidgets in the following way?

CFLAGS="-arch i386 -arch x86_64" CXXFLAGS="-arch i386 -arch x86_64" LDFLAGS="-arch i386 -arch x86_64" ./configure --with-macosx-sdk=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk --with-macosx-version-min=10.7 --with-cocoa

comment:8 Changed 8 years ago by vadz

If we want to handle multi-arch flags specified explicitly like this, i.e. not added by ourselves, we'd need some way of detecting the bitness of the programs we build. I thought we could use arch(1) for this but it doesn't seem to work without plist:

% gcc -arch i386 -arch x86_64 sizeof.c
% file a.out
a.out: Mach-O universal binary with 2 architectures
a.out (for architecture i386):  Mach-O executable i386
a.out (for architecture x86_64):        Mach-O 64-bit executable x86_64
% arch ./a.out
arch: Can't find any plists for a.out

It does work for running the selected arch though

% ./a.out
sizeof(short)=2
sizeof(int)=4
sizeof(long)=8
% arch -32 ./a.out
sizeof(short)=2
sizeof(int)=4
sizeof(long)=4
% arch -64 ./a.out
sizeof(short)=2
sizeof(int)=4
sizeof(long)=8

so we could use this, i.e. check if running "arch -32 command" succeeds. It wouldn't work for PPC (perhaps not a big loss) nor when cross-compiling however...

So this is trickier than I thought. I don't see any really good way to solve this right now. And the worst part is that if we get it wrong, the build would fail and not just produce a (harmless) warning so we really should avoid guessing the arch wrongly.

Maybe we could just use file(1) and check if it says anything about multiple architectures? Relying on parsing of its output doesn't look like a good idea but I don't see anything better.

comment:9 Changed 8 years ago by mojca

I would check if

file a.out | grep "\(i386\)\|\(ppc\)"

returns anything or nothing at all. In case it doesn't, the flag is not needed.

comment:10 Changed 8 years ago by vadz

This still wouldn't work when cross-compiling because under Linux I have just

% file a.out
a.out: Mach-O fat file with 2 architectures

so I thought to just test for "architectures" (plural).

comment:11 follow-up: Changed 8 years ago by mojca

But this test would only apply to Mac OS X, wouldn't it?

comment:12 Changed 8 years ago by mojca

Another option is using

/usr/bin/arch -arch i386 ./a.out

which either runs a program or ends up with

arch: Unsupported architecture: i386

But I would say that file should do the job equally well.

comment:13 in reply to: ↑ 11 Changed 8 years ago by vadz

Replying to mojca:

But this test would only apply to Mac OS X, wouldn't it?

It's possible (or at least used to be, as the cross-compiler I have only has 10.4 SDK which is not supported any longer by the latest svn trunk, unfortunately) to cross-compile for OS X from Linux. But this is, admittedly, rather rare because there is no official cross-compiler for OS X. So I guess using file or arch with a fallback for cross-compiling (test "$cross_compiling" != "no") would be ok.

comment:14 Changed 8 years ago by mojca

Since I have no idea how to plug this into configure.in - may I ask for your help or at least some hints?

In particular, I don't know how to compile a simple empty program (I see the code in configure, but in configure.in there must be some tricks to achieve that).

comment:15 Changed 8 years ago by vadz

You can use AC_COMPILE_IFELSE to test compilation, AC_LINK_IFELSE to try linking and AC_RUN_IFELSE to try running.

To update configure after modifying configure.in you need to run autoconf.

Changed 8 years ago by mojca

Patch that removes -framework QuickTime on Mac when building only for x86_64

comment:16 Changed 8 years ago by mojca

I haven never played with autoconf before, but I came up with the following suggestion:

-  EXTRA_FRAMEWORKS="-framework IOKit -framework Carbon -framework Cocoa -framework AudioToolbox -framework System -framework OpenGL -framework QuickTime"
+  EXTRA_FRAMEWORKS="-framework IOKit -framework Carbon -framework Cocoa -framework AudioToolbox -framework System -framework OpenGL"
+  if test "$cross_compiling" != "no"; then
+      dnl In case of cross-compiling for Mac on platforms other than Mac OS X
+      EXTRA_FRAMEWORKS="$EXTRA_FRAMEWORKS -framework QuickTime"
+  else
+      AC_LANG_PUSH(C++)
+      AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 0; }])],wx_nonempty_when_osx_also32bit=`file conftest$ac_exeext | grep "\(i386\)\|\(ppc\)"`)
+      AC_LANG_POP()
+      if test "x$wx_nonempty_when_osx_also32bit" != "x"; then
+          EXTRA_FRAMEWORKS="$EXTRA_FRAMEWORKS -framework QuickTime"
+      fi
+  fi

Please test and let me know if it makes any sense.

comment:17 Changed 8 years ago by mojca

PS: test for "architectures" could work in principle, but that still doesn't cover cases with i386 or ppc alone (a single 32-bit architecture), so an additional test would have to be done.

Btw: are you able to generate x86_64 Mac binaries on cross compiler on Linux?

comment:18 Changed 8 years ago by VZ

  • Resolution set to fixed
  • Status changed from confirmed to closed

(In [71086]) Don't link with QuickTime framework in 64 bit wxOSX builds.

This framework doesn't exist in 64 bits and so using it results in a warning
when building 64 bit libraries. Avoid this by omitting it if we are sure that
we target 64 bits only.

Closes #14144.

Note: See TracTickets for help on using tickets.