Installing Pork

These instructions are to install Pork on a Linux system.

Prerequisites

  • Flex >2.5.4 (flex-old on ubuntu)
  • Bison
  • GCC

Pork uses GCC to generate .i/.ii files (preprocessed C/C++) for Elsa to parse.

The recommended version of GCC is GCC 4.2.

Elsa (the C++ parser in Pork) has a hard time with some of the new features used in later GCC C++ headers. Our recent work has gotten Mozilla to compile with GCC 4.2. GCC 4.3 should also work fairly well, but there may be 5 or so files that Elsa can't parse.

To make Pork easy to use, you will want to install MCPP that integrates into GCC. You will probably want a separate GCC for this so you don't have to modify your standard system GCC. You can install GCC in the normal way in a special directory.

Build and Install MCPP

MCPP generates macro expansion comments that allow Pork's Elsa to undo macros, which is necessary in order to get exact position information.

To tell MCPP which gcc installation to integrate itself with, place the selected GCC bin dir as the first element of your path:

PATH=/bindir/of/my/gcc:$PATH

If you want to use a GCC that has binaries named something other than "gcc" and "g++", or you use "ccache" for you main gcc installation and want mcpp to override a separate installation, you need to pass the options "CC=gccXXX CXX=g++XXX" to "./configure". But don't give absolute paths there: MCPP won't build right. Instead, make sure the commands will be found on the PATH, as above.

svn co https://mcpp.svn.sourceforge.net/svnroot/mcpp/trunk mcpp
cd mcpp
./configure --enable-replace-cpp
make
sudo make install

Note: if you followed the Dehydra installation instructions for Linux and compiled your own gcc, then you should not need to "sudo" make install. If you run simply "make install" and see file permission errors, mcpp is likely trying to override your main gcc installation. Make sure that (1) your "$PATH" is correct; (2) you passed the correct "CC=..." and "CXX=..." to "./configure".

Install the Pork Stack

Pork is a set of tools written at Mozilla for refactoring C++. Pork's aim is to simply doing C/C++ refactoring through Elsa.

hg clone http://hg.mozilla.org/rewriting-and-analysis/pork/
cd pork
hg clone http://hg.mozilla.org/rewriting-and-analysis/elsa
./configure
make

Building Mozilla with MCPP

To build Mozilla with MCPP to generate annotated .ii files, use the following configure command:

ac_cv_visibility_hidden=no CC="gcc34 -save-temps -Wp,-W0,-K" CXX="g++ -save-temps -Wp,-W0,-K" CPPFLAGS=-DNS_DISABLE_LITERAL_TEMPLATE $srcdir/configure --enable-debug --disable-optimize --disable-accessibility --enable-application=browser --disable-crashreporter

Building will probably require disabling WARNINGS_AS_ERRORS:

make WARNINGS_AS_ERRORS=

"-Wp,-W0,-K" are options that get passed to MCPP. See the MCPP manual. In particular, -K tells MCPP to add the macro annotations we use to get exact source positions. C++ files from other projects can be preprocessed with gcc -E -Wp,-W0,-K.

Building a 32-bit MCPP on a 64-bit system

This is dark magic, and I hope I've got it right. First I built GCC in a separate --prefix=/builds/gcc-3.4.6-installed. Note: once you do this, you can only use this version of GCC in -m32 mode.

Apply this patch:

NOTE: this doesn't seem necessary in the latest version; CPPFLAGS is already an argument.

Index: src/set_mcpp.sh
===================================================================
--- src/set_mcpp.sh     (revision 78)
+++ src/set_mcpp.sh     (working copy)
@@ -35,14 +35,14 @@
 echo "  cd ${inc_dir}/mcpp-gcc"
 cd ${inc_dir}/mcpp-gcc
 if test ! -f gcc${gcc_maj_ver}${gcc_min_ver}_predef_std.h; then
-    echo "  generating g*.h header files"
-    ${CC} -E -xc -dM /dev/null | sort | grep ' *#define *_'       \
+    echo "  generating g*.h header files: ${CPPFLAGS}"
+    ${CC} ${CPPFLAGS} -E -xc -dM /dev/null | sort | grep ' *#define *_'       \
             > gcc${gcc_maj_ver}${gcc_min_ver}_predef_std.h
-    ${CC} -E -xc -dM /dev/null | sort | grep -E ' *#define *[A-Za-z]+'    \
+    ${CC} ${CPPFLAGS} -E -xc -dM /dev/null | sort | grep -E ' *#define *[A-Za-z]+'    \
             > gcc${gcc_maj_ver}${gcc_min_ver}_predef_old.h
-    ${CXX} -E -xc++ -dM /dev/null | sort | grep ' *#define *_'    \
+    ${CXX} ${CPPFLAGS} -E -xc++ -dM /dev/null | sort | grep ' *#define *_'    \
             > gxx${gcc_maj_ver}${gcc_min_ver}_predef_std.h
-    ${CXX} -E -xc++ -dM /dev/null | sort | grep -E ' *#define *[A-Za-z]+' \
+    ${CXX} ${CPPFLAGS} -E -xc++ -dM /dev/null | sort | grep -E ' *#define *[A-Za-z]+' \
             > gxx${gcc_maj_ver}${gcc_min_ver}_predef_old.h
 fi
 if test ${host_system} = SYS_CYGWIN; then

If you don't do this, MCPP will get the wrong set of automatic definitions and you'll end up with an unpleasant hybrid x86-64/i686 build system.

$ export PATH=/builds/gcc-3.4.6-installed/bin:$PATH
$ export CPPFLAGS=-m32
$ CC=gcc34 CXX=g++34 CPPFLAGS=-m32 LDFLAGS=-m32 ../src/configure --enable-replace-cpp --prefix=/builds/gcc-3.4.6-installed  --target=i686-pc-linux
$ make
$ make install program_transform_name=