Patch for compiling Ice with clang (and gcc4.7)
please see the attached patches that contain various fixes that enable Ice to compile using clang 3.0 and new versions of gcc. The patches have been tested (compilation and unit tests) using:
- clang 3.0:
- gcc 4.7.0 20120128
- gcc 4.2.1 (to make sure nothing broke and all changes are backwards compatible)
There are three patches attached, usually you only need one of them:
- ice_for_clang.patch.txt: This contains all changes for all compilers
- ice_for_clang_only.patch.txt: This contains only the changes necessary to compile using clang (smaller changeset)
- freebsd_port_devel_ice.patch.txt: Patch for FreeBSD ports (see below how to use)
All three patches also contain the patches http://www.zeroc.com/forums/patches/...ially-bad.html and http://www.zeroc.com/forums/patches/...d-support.html. Note that these changes only affect Ice for C++ and other language mappings have neither been changed nor tested.
What has been changed?
The patch fixes a couple of problems with the current implementation of Ice in terms of C++ standard compliance. The biggest issue is the way the upCast functions are overloaded. The standard says:
Since most of the upCast overloads are provided on incomplete types and after Handle has been included, the only way to lookup the correct overload (which has to be matching, since the forward declared types naturally don't provide any information on object hierarchy) is by ADL. For ADL to work, the overload has to be provided within the types namespace. Therefore a large portion of this patch is moving upCast overloads out of IceInternal into the Ice namespace. On the one hand this litters the Ice namespace with many different overloads of upCast, on the other this seemed the easiest and most straight forward solution within breaking any internals and massive testing. Since upCast is also used within generated code slice2cpp has been changed accordingly.
First, the compiler does unqualified lookup in the scope where the name was written. For a template, this means the lookup is done at the point where the template is defined, not where it's instantiated. Since Multiply hasn't been declared yet at this point, unqualified lookup won't find it.
Second, if the name is called like a function, then the compiler also does argument-dependent lookup (ADL). (Sometimes unqualified lookup can suppress ADL; see [basic.lookup.argdep]p3 for more information.) In ADL, the compiler looks at the types of all the arguments to the call. When it finds a class type, it looks up the name in that class's namespace; the result is all the declarations it finds in those namespaces, plus the declarations from unqualified lookup. However, the compiler doesn't do ADL until it knows all the argument types.
The patch also fixes a cyclic inclusion problem caused by clang's stricter evaluation of template types (throwing a forward declared exception from within a template class) and other minor declaration order problems and glitches (old) gcc was fine with.
The changes implemented for gcc 4.7 are mostly cosmetic, a lot of compiler warning suppression (NDEBUG/assert).
clang:Plain clang++, no further parameters (therefore C++03, system's stdc++)
gcc 4.7.1: CXX=g++47 -std=gnu++11 -I/usr/local/lib/gcc47/include/c++ -Wno-deprecated-declarations
gcc 4.2.1: g++
This didn't compile yet using -std=c++11 since there are unresolved issues with strtoll on my platform. Ultimately I would like to see this compile using clang, C++11 and clang's libc++. Right now I can't get my hands on it in a near production environment so this has to wait.
Instructions for FreeBSD ports
Assuming you want to compile Ice using clang:
Make sure you've set
(e.g. in your make.conf)
Make sure you have the latest port collection (portsnap fetch update) and patch the ice port using:
From there it's basically make install:
patch -p0 </path/to/freebsd_port_devel_ice.patch.txt
make install clean
After applying the patch, compiling Ice using clang works flawlessly and only a few intentional deprecation warnings show up. Switching to C++11 and clang's own libc++ will be the next logical step. Obviously I cannot give any guarantees for any of the code, but by all I can tell Ice behaves pretty much like it should.
Mac OS X Lion + clang confirmed
I just got confirmation that this builds just fine on Mac OS 10.7 (Lion) using clang 2.1, 2.9, 3.0 and 3.1. Thanks to Andrew Edem for torturing his poor little MacBook Air for these tests.
(Note that Josh's problems were caused by using an unpatched version of mcpp. We used MacPorts for our tests, which contains a patched version of mcpp already).
Please find attached the patch used (this is the original patch plus a one line change specific to Mac OS X as pointed out by Josh). This works on FreeBSD as well as on MacOS X.
Apply the patch using:
patch -p0 </path/to/ice_for_clang_2012-03-05.txt
I will post a patch specific to MacPorts at a later point.
Patch specific to MacPorts
Please find attached a patch specific to compile Ice using clang with MacPorts. This patch also contains the http://www.zeroc.com/forums/patches/...-spoofing.html.
sudo port selfupdate
sudo port clean ice-cpp
cd `port dir ice-cpp`
sudo patch -p0 < /path/to/patch.ice-cpp.macports.txt
sudo port install ice-cpp configure.compiler=clang
Patch committed to FreeBSD ports now
The patch has been committed to FreeBSD ports today. For details see also ports/165702: [maintainer update] [patch] devel/ice: Support clang and gcc47, security fixes, cleanup.
To upgrade to Ice 3.4.2_2 do:
portsnap fetch update
portupgrade -r devel/ice
Please note that you might have to recompile dependent software outside of the package system manually.
Fantastic work with confirmation !
I have gcc4.7 build systems on Solaris 10 and 11, Flavours of Linux and the favourite, FreeBSD.
Thus far your patch is great.
From my build platform I have initially tested the FreeBSD platform outside of ports, and have successfully built the tree bar a one liner.
diff -rau Ice-3.4.2/cpp/include/Slice/Preprocessor.h Ice-3.4.2.patch/cpp/include/Slice/Preprocessor.h
--- Ice-3.4.2/cpp/include/Slice/Preprocessor.h 2011-06-16 05:43:58.000000000 +1000
+++ Ice-3.4.2.patch/cpp/include/Slice/Preprocessor.h 2012-04-02 18:56:38.436115544 +1000
@@ -13,6 +13,7 @@
# include <stdio.h>
Otherwise business as usual.
Would be nice if the Ice team listens to the importance of Clang++ and the input of Asterix SCF in regards to library development for the C++ community.