Debian Package rebuild

Rebuild of the Debian archive with clang

By Sylvestre Ledru (Debian, IRILL). February 28th 2012 (clang 3.0), June 23th 2012 (clang 3.1), January 28th 2013 (clang 3.2), July 14th 2013 (clang 3.3), January 10th 2014 (clang 3.4), June 6th 2014 (clang 3.4.2)

Presentation

This document presents the result of the rebuild of the Debian archive (the distribution) with clang, a new C/C++ compiler.

clang is now ready to build software for production (either for C, C++ or Objective-C). This compiler is providing many more warnings and interesting errors than the gcc suite while not carrying the same legacy as gcc.
This rebuild has several goals. The first one is to prove (or not) that clang is a viable alternative. Second, building a software with different compilers improves the overall quality of code by providing different checks and alerts.

Rebuild results

The detailed list of errors:
21383 packages have been rebuild. Among them, 2040 (9.5 %) failed.
Most of the errors are explained with test cases.
Type of errorOccurrenceclang % / Debian %
Option -u not existing in clang 701 34.36% / 3.28% List of errors
Unknown argument 148 7.25% / 0.69% List of errors
Missing symbols at link time 141 6.91% / 0.66% List of errors
non-void function should return a value 105 5.15% / 0.49% List of errors
Some headers could not be found 94 4.61% / 0.44% List of errors
Security: Format string is not a string literal 43 2.11% / 0.2% List of errors
Usage of C++11 feature without the argument 35 1.72% / 0.16% List of errors
The build timeout 33 1.62% / 0.15% List of errors
No support of nested C function 32 1.57% / 0.15% List of errors
Expected declaration (#define missing?) 27 1.32% / 0.13% List of errors
Linker error 24 1.18% / 0.11% List of errors
Wrong C++ default declaration in a method 19 0.93% / 0.09% List of errors
Variable length array for a non POD (plain old data) element 18 0.88% / 0.08% List of errors
Wrong main declaration 17 0.83% / 0.08% List of errors
Redefinition failed 15 0.74% / 0.07% List of errors
Tautological comparison 15 0.74% / 0.07% List of errors
Conflicting types 14 0.69% / 0.07% List of errors
Unknown warning option 13 0.64% / 0.06% List of errors
Multiple definition 13 0.64% / 0.06% List of errors
Changes of default constructor 13 0.64% / 0.06% List of errors
Some files are gone in the process 11 0.54% / 0.05% List of errors
Variable length array in structure won't be supported 10 0.49% / 0.05% List of errors
Void function should not return a value 10 0.49% / 0.05% List of errors
Redefinition of a extern inline not supported in C99 9 0.44% / 0.04% List of errors
Unqualified lookup into dependent bases of class templates 9 0.44% / 0.04% List of errors
Unsupported argument with an other option 8 0.39% / 0.04% List of errors
Potential usage of an uninitialized variable 7 0.34% / 0.03% List of errors
Cannot use -o use multiple output 7 0.34% / 0.03% List of errors
Unused const variable 6 0.29% / 0.03% List of errors
Use of old GNU field designator 6 0.29% / 0.03% List of errors
Unqualified lookup in templates 6 0.29% / 0.03% List of errors
Forward declaration of class cannot have a nested name specifier 6 0.29% / 0.03% List of errors
Use of a keyword as dependant template name 5 0.25% / 0.02% List of errors
Header guard failure 5 0.25% / 0.02% List of errors
Binding of reference drops qualifiers 5 0.25% / 0.02% List of errors
Cannot find member in the struct 5 0.25% / 0.02% List of errors
Explicit Specialization after instantiation 5 0.25% / 0.02% List of errors
Argument unused caused failure 5 0.25% / 0.02% List of errors
Unknown/unexpected directive 5 0.25% / 0.02% List of errors
Wrong assumption about gcc/g++ output 4 0.2% / 0.02% List of errors
No matching member or constructor call 4 0.2% / 0.02% List of errors
Tautological pointer comparison - new in 3.5.0 4 0.2% / 0.02% List of errors
Unknown Type Name 4 0.2% / 0.02% List of errors
Linker option unused 4 0.2% / 0.02% List of errors
Unsupported option 4 0.2% / 0.02% List of errors
Mismatched Tags 3 0.15% / 0.01% List of errors
Unused function 3 0.15% / 0.01% List of errors
Object is not a function or function pointer 3 0.15% / 0.01% List of errors
Implicit instantiation 3 0.15% / 0.01% List of errors
Definition of a builtin function 3 0.15% / 0.01% List of errors
Comparison between pointer and integer 3 0.15% / 0.01% List of errors
Embedded directive has undefined behavior 3 0.15% / 0.01% List of errors
Cannot initialize a element 3 0.15% / 0.01% List of errors
No viable overloaded 3 0.15% / 0.01% List of errors
Unused parameter 3 0.15% / 0.01% List of errors
Member is not a structure or union 3 0.15% / 0.01% List of errors
No type named in namespace 3 0.15% / 0.01% List of errors
Access to a protected member 3 0.15% / 0.01% List of errors
Access to a private member 3 0.15% / 0.01% List of errors
Empty body declaration 3 0.15% / 0.01% List of errors
Default initialization needs a user-provided default constructor 3 0.15% / 0.01% List of errors
No matching function call 3 0.15% / 0.01% List of errors
read-only variable is not assignable 2 0.1% / 0.01% List of errors
Hides overloaded virtual function 2 0.1% / 0.01% List of errors
Explicitly assigning a variable of type 2 0.1% / 0.01% List of errors
Ambiguous declaration 2 0.1% / 0.01% List of errors
Parameter could be qualified 2 0.1% / 0.01% List of errors
Default arguments cannot be added to a function template (already declared) 2 0.1% / 0.01% List of errors
Functions differ only in their return type cannot be overloaded 2 0.1% / 0.01% List of errors
Visibility does not match previous declaration 2 0.1% / 0.01% List of errors
Enum Conversion 2 0.1% / 0.01% List of errors
Equality comparison with extraneous parentheses 2 0.1% / 0.01% List of errors
Initializer element not compile-time constant 2 0.1% / 0.01% List of errors
Reference to non-static member function must be called 2 0.1% / 0.01% List of errors
main function must return int 1 0.05% / 0% List of errors
Recursive template instantiation exceeded 1 0.05% / 0% List of errors
String + int 1 0.05% / 0% List of errors
Missing prototypes 1 0.05% / 0% List of errors
Unused private field 1 0.05% / 0% List of errors
restrict requires a pointer or reference 1 0.05% / 0% List of errors
Segmentation fault 1 0.05% / 0% List of errors
Cannot combine with previous declaration specifier 1 0.05% / 0% List of errors
Elaborated type refers to a typedef 1 0.05% / 0% List of errors
Configure failed 1 0.05% / 0% List of errors
Could not find a library 1 0.05% / 0% List of errors
Variable is uninitialized when used here 1 0.05% / 0% List of errors
Invalid instruction mnemonic 1 0.05% / 0% List of errors
Global register variable not supported 1 0.05% / 0% List of errors
Not categorized277 13.58% / 1.3% List of errors

Errors can be caused by several reasons:
Of course, a bug can hide other bugs.
Bugs (with patches) will be reported in the Debian bug tracker. They will be tagged as wishlist.

Detailed results

The full list of all the results with logs are available at the following URL:

Many issues listed in the 2.9 have been fixed with the version 3.0. However, due to the improvements of error detections and some more warnings, 3.1 triggers more failure than 3.0. Consequently, the percentage of failure changed from about 8 % to 12 %.

Build time, binary size or performances

For now, none of this aspect have been checked in this analyze. I will try to introduce some measures of build time in the next analyzes.
Some pointers:

Future

I will rebuild regularly the Debian archive with two goals in mind:
1) See which packages get fixed
2) See the impact of new clang releases

The next step I would like to achieve would be an automatic rebuild of each new packages in the Debian archive with clang.
To complete this goal, I proposed a Google Summer project called clang support for build services in the Debian context.

An other aspect I am working on is to rebuild the archive using its static analyzer: scan-build. scan-build provides a great detection on some painful bugs.

There are still some works to do in the LLVM/Clang world. libc++ should be packaged into Debian. LLDB should be ported to GNU/Linux.
I wrote an other GSoC subject called Provide an alternative to libstdc++ with libc++.


Conclusions

When I had the idea to rebuild Debian with a new compiler, I was expecting many issues and bugs caused by clang but I have been surprised to notice that most of the issues are either difference in C standard supported, difference of interpretation or corner cases.
My personal opinion is that clang is now stable and good enough to rebuild most of the packages in the Debian archive, even if many of them will need minor tweaks to compile properly.
In the next few years, coupled with better static analysis tools, clang might replace gcc/g++ as the C/C++ compiler used by default in Linux and BSD distributions.
The clang developers are progressing very fast: 14.5% of the packages were failing with version 2.9 against 8.8% with version 3.0 and 12.1% with 3.1.
Several major steps in the clang adoptions have been made like chromium/chrome being built by default with clang, Xcode providing clang by default, FreeBSD working on the gcc => clang switch, etc.
However, from Debian's point of view, one important step would be to make sure that clang manages correctly all Debian kernels and release architectures (11 official, 6 unofficial)


Annexes

Rebuild

The 2.9 and 3.0 rebuild itself have been done on a cluster called Grid 5000.
3.1, 3.2 and 3.3 rebuilds have been done on EC2, the Amazon cloud, sponsoring Debian.

Each packages in the Debian archive has been rebuild with the chroot described further.
For each packages failing to build from the source with clang, the package has been rebuild with a "normal" Debian sid chroot. If working, we considered that it was due to a clang bug. Otherwise, the package is not listed in this list.

Configuration of the chroot

The procedure for 2.9 & 3.0 was the following:
VERSION=4.6
cd /usr/bin
rm g++-$VERSION gcc-$VERSION cpp-$VERSION
ln -s clang++ g++-$VERSION
ln -s clang gcc-$VERSION
ln -s clang cpp-$VERSION
cd -

All packages of the archive (15658 sources packages) have been rebuild this chroot (even the one without any C or C++ code). Build dependencies used are the same as Debian. For example, that means that the libxml2 used to build a package will be the one from Debian, not the one built with clang.

From clang 3.1, with the EC2 Amazon cloud, an chroot-setup-commands is used for each sbuild to setup the environnement.
The init code is the following:
apt-get update

echo "Install of clang"
apt-get update
apt-get install --yes --no-install-recommends clang -t unstable

echo "Replace gcc, g++ & cpp by clang"

cd /usr/bin
VERSIONS="4.8 4.7 4.6"
for VERSION in $VERSIONS; do
rm g++-$VERSION gcc-$VERSION cpp-$VERSION
ln -s clang++ g++-$VERSION
ln -s clang gcc-$VERSION
ln -s clang cpp-$VERSION
done

echo "Block the installation of new gcc version"
echo "gcc-4.6 hold"|dpkg --set-selections
echo "cpp-4.6 hold"|dpkg --set-selections
echo "g++-4.6 hold"|dpkg --set-selections
echo "gcc-4.7 hold"|dpkg --set-selections
echo "cpp-4.7 hold"|dpkg --set-selections
echo "g++-4.7 hold"|dpkg --set-selections

echo "Check if gcc, g++ & cpp are actually clang"
gcc --version|grep clang > /dev/null || exit 1

The same procedure has been used for the 3.2 rebuild except that the clang packages have been rebuild for unstable (instead of the experimental packages).

Acknowledgments

Many thanks to Lucas Nussbaum for his time and patience (especially since I did a few screw up :p).
Stefano Zacchiroli for the review (among other things).
Thanks also to Grid 5000 for their infrastructure and Amazon for their credit to use AWS.