stripcc 0.2.0 releasedA little tool to remove unused code from C/C++ source files [中文版]


1, What can stripcc do

    In order to be applicable for more platform and situations, the projects based on C/C++ language often use many Conditional Compilation Statements. Although they are more applicable, the readability of the source code decreases at the same time. For example, there is a code fragment from stunnel-4.20:

void stunnel_info(int raw) {
    
char line[STRLEN];

 

    sprintf(line, "stunnel " VERSION " on " HOST " with %s",
        SSLeay_version
(SSLEAY_VERSION));
    
if(raw)
        log_raw
("%s", line);
    
else
        s_log
(LOG_NOTICE, "%s", line);

    safecopy
(line, "Threading:");
#ifdef USE_UCONTEXT
    safeconcat
(line, "UCONTEXT");
#endif
#ifdef USE_PTHREAD
    safeconcat
(line, "PTHREAD");
#endif
#ifdef USE_WIN32
    safeconcat
(line, "WIN32");
#endif
#ifdef USE_FORK
    safeconcat
(line, "FORK");
#endif

#ifdef HAVE_OSSL_ENGINE_H
    safeconcat
(line, " SSL:ENGINE");
#endif

    safeconcat
(line, " Sockets:");
#ifdef USE_POLL
    safeconcat
(line, "POLL");
#else /* defined(USE_POLL) */
    safeconcat
(line, "SELECT");
#endif /* defined(USE_POLL) */
#if defined(USE_WIN32) && !defined(_WIN32_WCE)
    
if(s_getaddrinfo)
        safeconcat
(line, ",IPv6");
    
else
        safeconcat
(line, ",IPv4");
#else /* defined(USE_WIN32) */
#if defined(USE_IPv6)
    safeconcat
(line, ",IPv6");
#else /* defined(USE_IPv6) */
    safeconcat
(line, ",IPv4");
#endif /* defined(USE_IPv6) */
#endif /* defined(USE_WIN32) */

#ifdef USE_LIBWRAP
    safeconcat
(line, " Auth:LIBWRAP");
#endif

    
if(raw)
        log_raw
("%s", line);
    
else
        s_log
(LOG_NOTICE, "%s", line);
}


    How do you think about the readability of it? Could you find out the useful parts for a special platform easily like linux? Below is the useful parts for linux(Fedora Core 3) produced by stripcc:
   

void stunnel_info(int raw) {
    
char line[STRLEN];

    
sprintf(line, "stunnel " VERSION " on " HOST " with %s",
        SSLeay_version
(SSLEAY_VERSION));
    
if(raw)
        log_raw
("%s", line);
    
else
        s_log
(LOG_NOTICE, "%s", line);

    safecopy
(line, "Threading:");
    safeconcat
(line, "PTHREAD");

    safeconcat
(line, " SSL:ENGINE");

    safeconcat
(line, " Sockets:");
    safeconcat
(line, "POLL");
    safeconcat
(line, ",IPv4");

    safeconcat
(line, " Auth:LIBWRAP");

    
if(raw)
        log_raw
("%s", line);
    
else
        s_log
(LOG_NOTICE, "%s", line);
}


    It is more clearly when you read it again.

    Sometimes a function may have different implementations for different platform. This is widely used by some projects need to support  several platform, such as linux kernel. When you use a source navigation tool like ctags or SourceInSight to read it, you will probably couldn't exactly locate the code you want.

    The goal of the stripcc is to resolve above problems. Simply Speaking, using stripcc you can remove unused code from your C/C++ based projects but the useful comments and original code style is reserved.

2, How does stripcc work

    The principles of stripcc are easy to understand:
    1, For each source file(such as *.c/*.h) in target directory, insert GCC expanding Pre-Compiled Statements
#warning to proper position.
    2, Build entire project and analyse the output of the GCC.
    3, According to the results of analysis to determine which parts of the source file should be remained and which parts should be removed.

    stripcc works reliably, it do not remove any useful source code from your project. But please note that before you using stripcc, the target project must be compiled successfully using
make or other commands.

3, How to use stripcc

    You need to download the source code of stripcc, the stripcc is released under GPL version 2, you can get it from http://sourceforge.net/projects/stripcc. Then decompress, compile and install it. The default location of stripcc will be installed is /usr/local/bin, you can change it by modify Makefile in stripcc source directory or manually copy binary file(stripcc) to anywhere. But be sure that the directory stripcc in is in your environment variable $PATH.

    After install, you can use stripcc. Note that before use it, you need back up your source code will be processed.

    You will see the following output when you run stripcc with the option "-h":

    $ stripcc -h
    Usage: stripcc <option(s)>
    Remove CCs(Conditional Compilation Branches) which won't be compiled from c/c++ source files under current directory.
     The options are:
      -c <str> Commands for build target program, "make" is default
      -m <str> Directory to run build commands, current directory is default
      -f       Working in fast mode (Experimental, NOT RECOMMENDED!)
      -n       Don't verify after strip
      -v       Display this program's version number
      -h       Display this output

    stripcc starts to support configuration file from version 0.2.0. It extremely improves the ability of the user to control the strip process. stripcc try to read the configuration file from the current directory of stripcc being called. The configuration file includes 5 sections:

    [strip_exts] indicates the files identified by the extension file name will be stripped, ".c" and ".h" are the default.
    [strip_dirs] indicates the directories will be stripped recursively, current directory "." is the default.
    [dont_strip_dirs] indicates the directories shouldn't be stripped.
    [strip_files] indicates the files that were not restricted by the extension file name will be stripped.
    [dont_strip_files] indicates the files that shouldn't be stripped.

    You can refer to the sample file "stripcc.conf" in stripcc's source package for the exact rule to write configuration file. Note that all paths of directory and file must use relative one to the directory of "stripcc.conf" in and all paths must starts with ".", like "./dir/file.c".

    If stripcc can't find "stripcc.conf", it will recursively strip all the files end with ".c" and ".h" in the current directory.

    We will take stunnel-4.21, lwip-0.5.3 and kernel-2.6.27.7 respectively for example to illustrate the usage of stripcc:

    1,stunnel-4.21


    $ tar zxf stunnel-4.21.tar.gz
    $ cd stunnel-4.21
    $ ./configure
    $ make

    After "make" complete, you can call stripcc. it will process all files in current directory recursively.
    $ stripcc
    o Getting a list of files which will be stripped...
      o Failed to open config file(./stripcc.conf), use the default values.
    o Backing up files...
    o Adding "#warning"...
    o Try to build target, this operation may takes a few minutes
    o Restore files...
    o Stripping files...
    o Start to verify
    o Done!

    Green "Done!" indicates the strip process works successfully.


   
    2
lwip-0.5.3


    $ tar zxf lwip-0.5.3.tar.gz
    $ cd lwip-0.5.3

    The main reason for taking lwip-0.5.3 as an example is that when you compile lwip, you need to run "make" in the subdirectory "proj/unixsim/".
    $ cd proj/unixsim/
    $ make

    Then we back to the top directory after the build complete.
    $ cd ..
    $ cd ..

    Run stripcc in the top directory and use "-m" option to tell the stripcc call "make" in "proj/unixsim/":
    $ stripcc -m "proj/unixsim"
    o Getting a list of files which will be stripped...
      o Failed to open config file(./stripcc.conf), use the default values.
    o Backing up files...
    o Adding "#warning"...
    o Try to build target, this operation may takes a few minutes.
    o Restore files...
    o Stripping files...
    o Start to verify
    o Done!


   
    3
kernel-2.6.27.7


    $ tar jxf linux-2.6.27.7.tar.bz2
    $ cd linux-2.6.27.7

    Choose the default configuration for x86:
    $ make defconfig
    $ make vmlinux

    Then we get the total amount of the source code before processing:
    $ totalcode
    totalline:  8410243

    The total amount of the source code is about 8,410,000 lines. Then we can start to process, because the build command is not "make" as the default of stripcc, so we need to use "-c" option tell stripcc use "make ARCH=um" instead of "make".
    $ stripcc -c "make vmlinux"
    o Getting a list of files which will be stripped...
      o Failed to open config file(./stripcc.conf), use the default values.
    o Backing up files...
    o Adding "#warning"...
      o Invalid source line(./arch/mips/kernel/sync-r4k.c: 159).
    o Try to build target, this operation may takes a few minutes.  
    o Restore files...
    o Stripping files...
    o Start to verify   
    o Done!

    Then we get the total amount of the source code after processing:
    $ totalcode
    totalline:  1287399

    The process cost about 4 times longer than the normal build. The total amount of the remaining source code is only 1,187,399 lines, about 85% of the original source code is discarded. Now if you use ctags you will feel more easy. In addition, because of we just used the default configuration values provided by the kernel package, there are a lot of drivers and modules we don't really need. If we disable those drivers/modules, we can easily reduce the total amount of the remaining source code less than 400,000 lines.



4Others
   
    1, What's new in stripcc-0.2.0?
        a, Add configuration file(stripcc.conf) support. Users can control the whole process of strip easily.
        b, Unlike stripcc-0.1.*, new stripcc will automatically ignore the syntax error in source files instead of report error and quit.
        c, Add fast strip mode, but unfortunately, it works not as good as i ever thought, so this function is just retained as an experimental feature.

    2, Which Hardwares and OSs are stripcc supported?
        Generally speaking, all hardware and POSIX OS which GCC can running on are supported. The below is a list of them which have been verified:

        solaris/t1000:
            -bash-3.00$ uname -a
            SunOS t1000 5.10 Generic_118833-33 sun4v sparc SUNW,Sun-Fire-T1000 Solaris

            -bash-3.00$ gcc --version
            sparc-sun-solaris2.10-gcc (GCC) 4.0.3 (gccfss)
            Copyright (C) 2006 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.

        solaris/x4100:
            -bash-3.00$ uname -a
            SunOS x4100 5.10 Generic_118855-33 i86pc i386 i86pc

            -bash-3.00$ gcc --version
            gcc (GCC) 3.4.3 (csl-sol210-3_4-branch+sol_rpath)
            Copyright (C) 2004 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.

        solaris/i386:
            -bash-3.00$ uname -a
            SunOS solaris 5.10 Generic_118855-33 i86pc i386 i86pc Solaris

            -bash-3.00$ gcc --version
            gcc (GCC) 3.4.3 (csl-sol210-3_4-branch+sol_rpath)
            Copyright (C) 2004 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.

        linux/x86_64:
            dugang@ubuntu:~/test$ uname -a
            Linux ubuntu 2.6.24-21-generic #1 SMP Tue Oct 21 23:09:30 UTC 2008 x86_64 GNU/Linux

            dugang@ubuntu:~/test$ gcc --version
            gcc (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu3)
            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.

        freebsd/amd64:
            -bash-2.05b$ uname -a
            FreeBSD freebsd.unix-center.net 6.2-RELEASE FreeBSD 6.2-RELEASE #0: Fri Jan 12 08:43:30 UTC 2007    
            root@portnoy.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP  amd64

            -bash-2.05b$ gcc --version
            gcc (GCC) 3.4.6 [FreeBSD] 20060305
            Copyright (C) 2006 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.

        aix/powerpc:
            -bash-3.00$ uname -a
            AIX aix 3 5 00C97AC04C00 powerpc unknown AIX

            -bash-3.00$ gcc --version
            gcc (GCC) 4.2.0
            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.

        linux/i386:
            [duxg@l151 stripcc]$ uname -a
            Linux l151 2.6.23.1-42.fc8 #1 SMP Tue Oct 30 13:55:12 EDT 2007 i686 i686 i386 GNU/Linux

            [duxg@l151 stripcc]$ gcc --version
            gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-33)
            Copyright (C) 2006 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.

    3, How about the C/C++ language standards support in stripcc?
        stripcc conforms to C99 and also support some features extended by GCC. The only conflict with C99 is that C99 said the newline character in multi-line comments(/* ... */) that should be retained, but stripcc discards it as what was GCC done.
        stripcc hasn't done anything specially for C++ support.

5Known problems

    1, Since the limitation of the working principle of stripcc, There are some problems when use stripcc to strip project which turned GCC option "-Werror" on. so if stripcc report error, you should check the GCC's options of your project first.

    2, stripcc can't process the project which generates new source file from other source file during the build time. The known projects did this include GCC and Ethereal. There was no problem for those prjects which generate source file from non-C source file, like from *.lex/*.y(lex/yacc's source file).

6Acknownagement
  
    I sincerely thank the people for stripcc use and helpful suggestions, especially fangmz, harite.k, xishipan.


    If you have any idea or comment on stripcc, let me know please.

    My EMail: dugang@188.com.

    Thanks!