Bug 300429 - __KDE_HAVE_GCC_VISIBILITY not defined on Apple OS X 10.7.4 Lion
Summary: __KDE_HAVE_GCC_VISIBILITY not defined on Apple OS X 10.7.4 Lion
Status: RESOLVED FIXED
Alias: None
Product: buildsystem
Classification: Developer tools
Component: KDE4 (cmake) (show other bugs)
Version: unspecified
Platform: unspecified macOS
: NOR normal
Target Milestone: ---
Assignee: Alexander Neundorf
URL:
Keywords:
: 300426 300427 300428 (view as bug list)
Depends on:
Blocks: 313763
  Show dependency treegraph
 
Reported: 2012-05-22 05:20 UTC by Ian Wadham
Modified: 2013-08-21 22:49 UTC (History)
6 users (show)

See Also:
Latest Commit:
Version Fixed In: 4.11.1


Attachments
CMake output from failed build (6.78 KB, application/octet-stream)
2012-05-22 05:22 UTC, Ian Wadham
Details
/opt/local/include/kdemacros.h from my machine (13.44 KB, text/x-chdr)
2012-07-23 03:42 UTC, Ian Wadham
Details
CMake output from building KDE Libs (27.79 KB, application/octet-stream)
2012-07-29 05:00 UTC, Ian Wadham
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ian Wadham 2012-05-22 05:20:45 UTC
On Apple Macbook Pro with OS X 10.7.4 Lion and XCode 4.2.1, I have installed Macports 2.0.4, kdelibs4 @4.8.2_0, kde4-runtime @4.8.2_0 and qt4-mac @4.7.4_1.  I also have a development version of KDE Games, where I am one of the developers.  Recently I have been unable to compile and link KDE Games, because it gets undefined symbols every time the build tries to link to a library that has just been built.

By reducing the build down to one KDE Games library and one game, I was able to establish that KDE_EXPORT is evaluating to a null string and so is KDEGAMES_EXPORT, which is derived from KDE_EXPORT, consequently no library symbols are made visible.  Looking at <prefix>/include/kdemacros.h, I find that KDE_EXPORT depends on __KDE_HAVE_GCC_VISIBILITY and that macro is not defined (null) in my system.  If I insert a line "add_definitions (-D__KDE_HAVE_GCC_VISIBILITY)" into kdegames/CMakeLists.txt, just after adding KDE4_DEFINITIONS, the build works fine.  So I have a workaround.

I think the problem has arisen because of a recent switch to a different compiler in Macports or XCode.  CMake is using /usr/bin/c++, which is symbolically linked to /usr/bin/llvm-g++-4.2.  Compilation was previously (up till a few weeks ago) using /usr/bin/llvm-cpp-4.2, which gave no problems.

Attached is my CMake output.


Reproducible: Always

Steps to Reproduce:
1. Compile and build KDE Games on Apple Lion using  /usr/bin/llvm-g++-4.2.
2. For further details see above and attached CMake output.
3.
Actual Results:  
Linking CXX executable bomber.app/Contents/MacOS/bomber
Undefined symbols for architecture x86_64:
  "KgThemeProvider::KgThemeProvider(QByteArray const&, QObject*)", referenced from:
      Bomber::Bomber()in bomber.o
      Bomber::Bomber()in bomber.o
  "KgThemeProvider::discoverThemes(QByteArray const&, QString const&, QString const&, QMetaObject const*)", referenced from:
      Bomber::Bomber()in bomber.o
      Bomber::Bomber()in bomber.o


Expected Results:  
No undefined symbols.
Comment 1 Ian Wadham 2012-05-22 05:22:30 UTC
Created attachment 71282 [details]
CMake output from failed build
Comment 2 Ian Wadham 2012-05-22 06:03:33 UTC
*** Bug 300426 has been marked as a duplicate of this bug. ***
Comment 3 Ian Wadham 2012-05-22 06:04:18 UTC
*** Bug 300427 has been marked as a duplicate of this bug. ***
Comment 4 Ian Wadham 2012-05-22 06:05:05 UTC
*** Bug 300428 has been marked as a duplicate of this bug. ***
Comment 5 Ian Wadham 2012-05-22 06:08:47 UTC
Sorry about all the duplicates.  Bugzilla was failing to respond after I had typed in all the descriptions.  So I was hitting Stop and trying again.
Comment 6 Ian Wadham 2012-05-24 21:41:18 UTC
FYI I have also filed a ticket at the Macports end, see https://trac.macports.org/ticket/34605?replyto=1#comment  Hoping you can help each other.
Comment 7 Raphael Kubo da Costa 2012-07-21 19:48:18 UTC
(In reply to comment #0)
> On Apple Macbook Pro with OS X 10.7.4 Lion and XCode 4.2.1, I have installed
> Macports 2.0.4, kdelibs4 @4.8.2_0, kde4-runtime @4.8.2_0 and qt4-mac
> @4.7.4_1.  I also have a development version of KDE Games, where I am one of
> the developers.  Recently I have been unable to compile and link KDE Games,
> because it gets undefined symbols every time the build tries to link to a
> library that has just been built.
[snip]
> I think the problem has arisen because of a recent switch to a different
> compiler in Macports or XCode.  CMake is using /usr/bin/c++, which is
> symbolically linked to /usr/bin/llvm-g++-4.2.  Compilation was previously
> (up till a few weeks ago) using /usr/bin/llvm-cpp-4.2, which gave no
> problems.

It's hard for me to help because I do not have a Mac, but from your
description it looks like the compiler is not being recognized as GCC
anymore, so FindKDE4Internal.cmake in kdelibs/cmake/modules is not
checking if -fvisibility=hidden is present anymore.

Can you provide the output of `llvm-cpp-4.2 --version' and
`llvm-g++-4.2 --version'?

> defined (null) in my system.  If I insert a line "add_definitions
> (-D__KDE_HAVE_GCC_VISIBILITY)" into kdegames/CMakeLists.txt, just after
> adding KDE4_DEFINITIONS, the build works fine.  So I have a workaround.

I _think_ if you pass -D__KDE_HAVE_GCC_VISIBILITY=TRUE to CMake it
also works without the need to patch the code.
Comment 8 Ian Wadham 2012-07-22 07:45:47 UTC
Thanks for looking at this. Here is the information you requested:
Tara:~>llvm-cpp-4.2 --version
llvm-cpp-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Tara:~>which llvm-g++-4.2
/usr/bin/llvm-g++-4.2
Tara:~>llvm-g++-4.2 --version
i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Please also note https://trac.macports.org/ticket/34605?replyto=1#comment
report at the Macports.  Maybe the guys who port KDE to Mac can help you further, but I have not yet had a reply from them.
Comment 9 Raphael Kubo da Costa 2012-07-22 18:30:57 UTC
Hmm, according to the build output you attached the compiler is still being recognized as GNU, and the check for __KDE_HAVE_GCC_VISIBILITY is succeeding.

How does MacPorts work? Does it build kdelibs on your own machine? If so, can you also post the CMake output from building kdelibs?

Attaching /opt/local/include/kdemacros.h would also be helpful.
Comment 10 Ian Wadham 2012-07-23 03:34:20 UTC
(In reply to comment #9)
> Hmm, according to the build output you attached the compiler is still being
> recognized as GNU, and the check for __KDE_HAVE_GCC_VISIBILITY is succeeding.
> 
No. That was to show what libraries, etc. my build is using and to illustrate my workaround of defining   __KDE_HAVE_GCC_VISIBILITY in CMakeLists.txt. When I take out that definition, no more message about it.  A normal build is silent on the subject of  __KDE_HAVE_GCC_VISIBILITY being defined (via kdemacros.h).

What happens is that, if  __KDE_HAVE_GCC_VISIBILITY is undefined, KDE_EXPORT evaluates to a null string and the first library method my code tries to link in causes horrible death of the build and unhelpful diagnostics from the ld command.  Library symbols are diagnosed as undefined, when they are clearly present in the source code and have been for some months or years.  See the attachments to http://lists.kde.org/?l=kde-games-devel&m=133628029917318&w=2 for what happens when this bug strikes.

It would be helpful if KDE would assign some invalid string to KDE_EXPORT when it meets a strange compiler, then at least we could get a compiler diagnostic in the line that caused the problem.  It cost me a week or two to get to the bottom of this problem and report it here.

> How does MacPorts work? Does it build kdelibs on your own machine? If so,
> can you also post the CMake output from building kdelibs?
> 
> Attaching /opt/local/include/kdemacros.h would also be helpful.

MacPorts is something like kdesrc-build only more so.  It covers virtually all open source code.  By default, every ported package you may request is downloaded in source code form, including Qt4-mac and KDE libs.  When you install it, it depends on some Apple command-line tools (e.g. OS X, which is derived from BSD).  Then Macports has a huge database of ports, versions and dependencies.  So if you start by asking for kdegames4 @4.8.2_0+docs you are in for an all-night build session, because it must first download, compile and build every last dependency, i.e. large parts of a typical Linux installation.

So, in brief, yes.  Macports does download the source code of kdelibs and compiles and builds it on my machine.

Getting the CMake output from building kdelibs would be quite a lot of work for me and I would probably have to begin by asking the Macports list how to do it.  Do you reallly need it that badly?  It is not as simple as asking for one module in kdesrc-build, because of all the distro-type stuff that goes on behind the scenes in Macports, which is effectively a distro for Apple platforms.

I am attaching my /opt/local/include/kdemacros.h.  I have patched it to define  __KDE_HAVE_GCC_VISIBILITY.  Yeah, I know that is a no-no: the file is generated and will get over-written next time I install, but this is for me the easiest way to "set and forget" my workaround for this bug.
Comment 11 Ian Wadham 2012-07-23 03:42:17 UTC
Created attachment 72693 [details]
/opt/local/include/kdemacros.h from my machine
Comment 12 Raphael Kubo da Costa 2012-07-23 04:13:29 UTC
(In reply to comment #10)
> (In reply to comment #9)
> > Hmm, according to the build output you attached the compiler is still being
> > recognized as GNU, and the check for __KDE_HAVE_GCC_VISIBILITY is succeeding.
> > 
> No. That was to show what libraries, etc. my build is using and to
> illustrate my workaround of defining   __KDE_HAVE_GCC_VISIBILITY in
> CMakeLists.txt.

OK, this makes more sense than the previous results. 

> When I take out that definition, no more message about it. 
> A normal build is silent on the subject of  __KDE_HAVE_GCC_VISIBILITY being
> defined (via kdemacros.h).

kdemacros.h doesn't really matter at this point. The problem happens earlier, at the moment FindKDE4Internal.cmake is run. You should at least get the following output when running CMake:

  -- Performing Test __KDE_HAVE_GCC_VISIBILITY
  -- Performing Test __KDE_HAVE_GCC_VISIBILITY - Failed

If you don't change anything and the test still succeeds, the failure is somewhere else. If the test does fail, it would be really useful to have access to your CMakeFiles/CMakeError.log (which is in your kdelibs build directory) -- it contains the program and the arguments passed to the compiler which made the test fail, as well as the compiler's error message.
Comment 13 Ian Wadham 2012-07-26 00:23:41 UTC
I will try to get the CMake output from Macports' build of kdelibs4 @4.8.2_0, but it will take a while - there are no logs left behind from the previous build.  Meanwhile another Macports developer has taken assignment of my Macports ticket at https://trac.macports.org/ticket/34605?replyto=1#comment and I have asked for him to get in touch with you.  He should be able to provide better information than me.
Comment 14 Ian Wadham 2012-07-29 05:00:36 UTC
Created attachment 72809 [details]
CMake output from building KDE Libs
Comment 15 Ian Wadham 2012-07-29 05:01:57 UTC
I have now obtained the CMake output you require and will attach it.  On looking at the log, I think I can see what my problem has been.  Kdelibs4 @4.8.2 on Macports is actually compiled by the Apple compiler called "clang" --- clang 3.0 on my machine.  However, the OS X installation has /usr/bin/c++ linked to llvm-g++-4.2, a different compiler, for which would require different KDE CMake macros I presume.

If I go in as "root" and change /usr/bin/c++ to link to clang, all my compilations and builds of my KDE Games trunk code go fine, regardless of __KDE_HAVE_GCC_VISIBILITY.  Now there are two more questions.

1. Can you recommend a better way to convince CMake to use clang?

2. Should KDE libs assume that the same compiler or type of compiler is being used both to build KDE libs and to compile code for users of KDE libs?

The latter is usually a safe assumption in a Linux environment, but not at the moment in Apple OS X, where the compiler situation is somewhat fluid.  OTOH I am probably the only KDE developer using an Apple machine, so I do not expect you to change the KDE libs build scripts on my behalf ... :-)
Comment 16 Raphael Kubo da Costa 2012-07-30 05:36:00 UTC
(In reply to comment #15)
> I have now obtained the CMake output you require and will attach it.  On
> looking at the log, I think I can see what my problem has been.  Kdelibs4
> @4.8.2 on Macports is actually compiled by the Apple compiler called "clang"
> --- clang 3.0 on my machine.  However, the OS X installation has
> /usr/bin/c++ linked to llvm-g++-4.2, a different compiler, for which would
> require different KDE CMake macros I presume.
>
> If I go in as "root" and change /usr/bin/c++ to link to clang, all my
> compilations and builds of my KDE Games trunk code go fine, regardless of
> __KDE_HAVE_GCC_VISIBILITY.  Now there are two more questions.

Thanks for the investigation.  I don't really understand how kdelibs ends up
being built with clang by default while the rest of KDE is not (I am assuming
Macports is responsible for that).

Anyway, from what you describe the problem comes from the lack of proper
support for clang in kdelibs: there isn't a specific block for it like there is
for gcc or Intel's compiler, so some default compiler flagsare not set and some
feature tests (such as the visibility one) are not performed.

As for the gory details: in the specific case of the visibility test, this also
means that the default visibility settings will be used in this case (which
means everything will be exported by default).  If you then use clang to build
something else (like KDE Games) and link against the kdelibs version you built,
it will work because the necessary symbols will be there and, since the default
visibility settings are passed to the compiler, the new symbols will also be
exported just fine.  If, on the other hand, you build kdelibs with clang and
then use gcc to build KDE Games, kdelibs will have been built with all the
required symbols, but kdemacros.h will have the __KDE_HAVE_GCC_VISIBILITY
unset.  This, together with FindKDE4Internal.cmake making -fvisibility=hidden
be passed to gcc, will result in the symbols in KDE Games not being exported by
default (and since KDE_EXPORT and similar macros evaluate to nothing, the
symbols will not be exported at all).

> 1. Can you recommend a better way to convince CMake to use clang?

This really depends on how you are building $SOFTWARE. If you are using
Macports, you will probably need to ask the Macports folks how to do that. If
you are calling CMake yourself (as I assume to be the case with KDE Games), you
can simply pass -DCMAKE_C_COMPILER="clang" and -DCMAKE_CXX_COMPILER="clang++"
to it.

> 2. Should KDE libs assume that the same compiler or type of compiler is
> being used both to build KDE libs and to compile code for users of KDE libs?

Not really, but this in itself should not be a problem.  The issue at stake
here is lack of proper support for one of the compilers by kdelibs.

> OTOH I am probably the only KDE developer using an Apple machine, so I do
> not expect you to change the KDE libs build scripts on my behalf ... :-)

This problem in clang also interests me as a FreeBSD user/packager/developer,
since the project is also moving towards making it the default compiler in the
future.

I recommend either always using gcc or always using clang (the latter will
produce larger binaries since all symbols are going to be exported) until I (or
someone else with the same itch to scratch) add proper support for clang to
kdelibs' CMake files.
Comment 17 Ian Wadham 2012-07-30 12:37:00 UTC
(In reply to comment #16)
> (In reply to comment #15)
> Thanks for the investigation.  I don't really understand how kdelibs ends up
> being built with clang by default while the rest of KDE is not (I am assuming
> Macports is responsible for that).
> 
Macports depends on XCodes to provide compilers and UNIX command-line utilities.  XCode is a package for Apple developers.  From XCode 4.2 onward (i.e. since early this year), Macports policy has been to use clang.  I have confirmed this on the Macports users mailing list.  Macports supports earlier versions of Apple's OS X and XCode, but for those it uses GCC compilers.

Actually, the "rest of KDE" *is* compiled by Macports using clang, if you have XCode 4.2+.  That is to say, ports of *released* KDE modules and apps are compiled using clang.  For example, I have ports of KDE Games 4.8.2 and KMyMoney4 and their dependencies, such as KDE runtime and KDE PIM libs, all compiled by clang.  I use these ports for day-to-day work outside of what I do for KDE development.

I also have a SVN trunk version of KDE Games.  That is the code that was picking up a GCC compiler from OS X and failing to link to KDE libs compiled with clang.  Actually, the rot set in as soon as KDE Games tried to link to one of its own library classes in libkdegames, because they use KDE_EXPORT macros.

From now on I will set up CMake to use clang, in the way you have advised.  Thank you for that, Raphael.

> This problem in clang also interests me as a FreeBSD user/packager/developer,
> since the project is also moving towards making it the default compiler in the future.
> 
That is good to hear.  I had one or two problems earlier when clang diagnosed errors in legacy KDE Games code that had lain dormant and undiagnosed by GCC for years.  They were easy to fix, but clang seems to be a more rigorous compiler than KDE is currently using in Linux.

Thank you for your interest in this problem, Raphael.
Comment 18 Alberto Villa 2013-06-06 11:04:23 UTC
Visibility not being set for Clang causes at least a bug with some plasmoids (#313763). Adding a check (or even sharing GCC ones) to FindKDE4Internals.cmake should be trivial.
Comment 19 Raphael Kubo da Costa 2013-08-21 10:45:03 UTC
At last!

I've just committed http://quickgit.kde.org/?p=kdelibs.git&a=commit&h=90cb7ba760584a8010afef65fa14e649195af6c6 (it should have posted a comment in this bug but I used the wrong email address to commit :-)

After commits 7148da9c94527ced3804c39662fa48756b091178 (present in 4.11.0) and 90cb7ba760584a8010afef65fa14e649195af6c6 (will be in 4.11.1), clang support should finally be in place, with proper visibility and all.
Comment 20 Ian Wadham 2013-08-21 22:49:32 UTC
Thanks, Rafael.  I have passed your info on to the Macports developers list.