GCCSense 配置与用法

from: http://cx4a.org/software/gccsense/manual.html#Editros

1. Introduction

1.1. What is GCCSense ?

GCCSense is the most intelligent development tools for C/C++ using GCC's code analyzers. Using internal compiler information, it is capable to provide a high precise code completion functions. GCCSense is a standalone program, so any editors can use it.

1.2. Features

  • High precise code completion
  • Automatic syntax check

2. Downloads

You can download from GCCSense top page.

3. Installation

Before installation, please download a proper version of GCCSense and gcc-code-assist from the above download page.

3.1. Requirements

UNIX-like system that can build GCC is required. Currently Windows is not supported, but in the future, it will be supported by combining with MinGW.

3.2. Pre-Installation

Install required packages that is needed for GCCSense and for building GCC.

3.2.1. Debian Systems

$ sudo apt-get install build-essential libgmp3-dev libmpfr-dev flex ruby rubygems libsqlite3-ruby

3.2.2. FreeBSD Systems

Install the following ports packages.

  • textproc/flex
  • lang/ruby18
  • devel/ruby-gems
  • databases/sqlite3
  • databases/rubygem-sqlite3
  • math/libgmp4
  • math/mpfr
  • devel/gmake

Install like:

# foreach p ( textproc/flex lang/ruby18 devel/ruby-gems databses/sqlite3 databases/rubygem-sqlite3 math/libgmp4 math/mpfr devel/gmake )
cd /usr/ports/$p
make install
end

3.2.3. Mac OS X

Install MacPorts first.

After install MacPorts, install required packages using port like:

$ sudo port install gmp mpfr flex rb-rubygems
$ sudo gem install sqlite3-ruby

3.3. Install gcc-code-assist

gcc-code-assist is a custom GCC that has functions such as code completion. Basically follow GCC build instructions. Explain for specific platforms here.

The most important instructions is install directory and program suffix. Without specifying install directory, it would be /usr/local. If you install in normal user, you need to specify --prefix=$HOME to configure script and add $HOME/bin to PATH environment variable.

Program suffix is not actually required, but it should be because a name of existed GCC would may conflict to the custom GCC. GCCSense recommends to use -code-assist as program suffix. By this, gcc turns to gcc-code-assist and g++ turns to g++-code-assist. To specify program suffix, give --program-suffix=-code-assist to configure script.

The build will be finished in 30 minutes in recent PC.

After installation, make sure that gcc-code-assist and g++-code-assist can run.

$ gcc-code-assist --version
$ g++-code-assist --version

3.3.1. Debian Systems

$ tar xvjf gcc-code-assist-*.tar.bz2
$ cd gcc-code-assist-*
$ ./configure --program-suffix=-code-assist --enable-languages=c,c++ --disable-bootstrap --disable-multilib
$ make # -j2
$ sudo make install

3.3.2. FreeBSD Systems

# tar xvjf gcc-code-assist-*.tar.bz2
# cd gcc-code-assist-*
# ./configure --program-suffix=-code-assist --enable-languages=c,c++ --disable-bootstrap --disable-multilib
# gmake # -j2
# gmake install

3.3.3. Mac OS X

$ tar xvjf gcc-code-assist-*.tar.bz2
$ cd gcc-code-assist-*
$ ./configure --program-suffix=-code-assist --enable-languages=c,c++ --disable-bootstrap --disable-multilib --disable-nls --with-gmp-include=/opt/local/include --with-gmp-lib=/opt/local/lib --with-mpfr-include=/opt/local/include --with-mpfr-lib=/opt/local/lib --with-libiconv-prefix=/usr
$ make # -j2
$ sudo make install

3.4. Install GCCSense

It is easy to install GCCSense. Just add bin directory to PATH environment variable, or copy programs under bin directory to directoryes that are included in PATH environment variables. Generally you choose latter. This is not required, but setting for edits will be need anyway if you don't do it here.

$ cd gccsense-*
$ sudo cp bin/* /usr/local/bin/

We assume here that /usr/local/bin is included in PATH environment varialbe. It is also OK /usr/bin if you don't mind.

Finally, make sure that gccrec and autopch can run.

$ gccrec --version
gccrec 0.0.1
$ autopch --version
autopch 0.0.1

3.5. Install Emacs Extension

An Emacs extension is found at etc/gccsense.el. Just copy to directories that is included in load-path variable.

$ cp etc/gccsense.el ~/.emacs.d/

Write the following code into ~/.emacs.

(require 'gccsense)

3.6. Install Vim Plugin

A Vim plugin is found at etc/gccsense.vim. Just copy to ~/.vim/plugin, nothing is neede without copying.

$ cp etc/gccsense.vim ~/.vim/plugin

4. Usage

GCCSense is made of the following four pats. Sections you should read are emphasised.

  • gcc-code-assist

    A custom GCC that has functions such as code completion

  • gccrec

    A GCC wrapper for recording and replaying GCC command

  • autopch

    A GCC wrapper for enabling precompiled header automatically

  • Editros

    Editos such like Emacs and Vim

4.1. gcc-code-assist

gcc-code-assist is A custom GCC that has functions such as code completion. It is based on GCC 4.4 and has compatibilities. Functions currently available are following.

4.1.1. Code Completion

Specifying a completion postion with -code-completion-at option, gcc-code-assist outputs completion candidates for the position. Option will take a value of forma of <file>:<line>:<column>. <file> and a file name given to compiler have to be matched. <line> and <column> are 1 based. Consider an example.

$ nl test.cpp
     1  #include <string>
     2  int main()
     3  {
     4      std::string s;
     5      s.
     6  }
$ # Outputs candidates starting with c at line 5 column 7 of test.cpp
$ g++-code-assist -fsyntax-only -code-completion-at=test.cpp:5:7 test.cpp 2> /dev/null | grep '^completion: c'
completion: capacity "typename _Alloc::rebind<_CharT>::other::size_type std::basic_string<_CharT, _Traits, _Alloc>::capacity() const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]"
completion: clear "void std::basic_string<_CharT, _Traits, _Alloc>::clear() [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]"
completion: copy "typename std::basic_string<_CharT, _Traits, _Alloc>::size_type std::basic_string<_CharT, _Traits, _Alloc>::copy(_CharT*, typename _Alloc::rebind<_CharT>::other::size_type, typename _Alloc::rebind<_CharT>::other::size_type) const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]"
completion: c_str "const _CharT* std::basic_string<_CharT, _Traits, _Alloc>::c_str() const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]"
completion: compare "int std::basic_string<_CharT, _Traits, _Alloc>::compare(const std::basic_string<_CharT, _Traits, _Alloc>&) const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]"
completion: compare "int std::basic_string<_CharT, _Traits, _Alloc>::compare(typename _Alloc::rebind<_CharT>::other::size_type, typename _Alloc::rebind<_CharT>::other::size_type, const std::basic_string<_CharT, _Traits, _Alloc>&) const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]"
completion: compare "int std::basic_string<_CharT, _Traits, _Alloc>::compare(typename _Alloc::rebind<_CharT>::other::size_type, typename _Alloc::rebind<_CharT>::other::size_type, const std::basic_string<_CharT, _Traits, _Alloc>&, typename _Alloc::rebind<_CharT>::other::size_type, typename _Alloc::rebind<_CharT>::other::size_type) const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]"
completion: compare "int std::basic_string<_CharT, _Traits, _Alloc>::compare(const _CharT*) const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]"
completion: compare "int std::basic_string<_CharT, _Traits, _Alloc>::compare(typename _Alloc::rebind<_CharT>::other::size_type, typename _Alloc::rebind<_CharT>::other::size_type, const _CharT*) const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]"
completion: compare "int std::basic_string<_CharT, _Traits, _Alloc>::compare(typename _Alloc::rebind<_CharT>::other::size_type, typename _Alloc::rebind<_CharT>::other::size_type, const _CharT*, typename _Alloc::rebind<_CharT>::other::size_type) const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]"

An output format is completion: <name> "<summary>".

Currently, code completion is available for C/C++. No need to say, code completion can be used in any code that is able to be compiled with GCC 4.4. Code completion is enabled after . and -> in C, and :: in C++.

4.2. gccrec

It seems to be not difficult story to realize code completion in editors by using code completion command that is described in the previous section. Basically, that is true, however there is a big problem that editors can never know GCC compiler options for an editing file. Consider the following command.

$ gcc -I../some/include/path -DSOME_SWITCH -c test.cpp

test.cpp may include some headers from ../some/include/path, and errors may occur without SOME_SWITCH enabled. Probably code completion will be ended with errors in such cases. And in general, there command is written in Makefile, so it is difficult to get valid compiler options.

gccrec is a GCC wrapper for resolving that problem. GCC wrapper is a program that behaves as GCC but perform some special processes around the compilation. gccrec records a mapping of a source file and the compiler options to a database before delegating to GCC. After recording, you can replay the command by giving the source file.

Consider the following example.

$ gcc -I../some/include/path -DSOME_SWITCH -c test.c

To recrod, put gccrec before gcc.

$  gccrec gcc -I../some/include/path -DSOME_SWITCH -c test.c

gccrec will extract a source file (test.c in this case) from the compiler options, and will records a mapping to the database.

The database is located at ~/.gccrec in a format of SQLite3. Let's peek a little.

$ sqlite3 ~/.gccrec
sqlite> select file, args from gccrec;
/home/tomo/tmp/test.c|-I../some/include/path -DSOME_SWITCH -c

You may see the mapping is recorded. To replay the recorded command, execute gccrec with -r option and the soruce file.

$ gccrec -r test.c

By specifying -v option, you can see the actual command in output.

$ gccrec -v -r test.c
gcc -I../some/include/path -DSOME_SWITCH -c /home/tomo/tmp/test.c

You may realize already, editors will use gccrec command with giving a editing file for compilation and code completion.

Give a mimic example. First of all, users have to recrod a compiler options with gccrec. Note that you have to record with gcc-code-assist or g++-code-assist not gcc and g++ so that code completion will be available later.

$ gccrec g++-code-assist -c test.cpp

When code completion requested, editors interanlly executes the following command.

$ gccrec -v -r test.cpp -fsyntax-only -code-completion-at=$PWD/test.cpp:5:7
completion: ...

It is important that recording the compiler options with gccrec first. It is all you need to do.

4.2.1. Build Tools Support

Many projects use build tools such like make. In such projects, it is hard to record all of source files manually. gccrec can handle such cases.

Generally, Makefile can take CC and CXX from external like:

$ make CC='my-gcc' CXX='my-g++'

You can record all of source files in the project by using this characteristic.

$ make clean
$ make CC='gccrec gcc-code-assist' CXX='gccrec g++-code-asssist'

Actual completion will be done during record. It is because of making recording success as much as possible.

Many records will be recorded at ~/.gccrec. You don't need to do this again unlesss the compiler options is changed or a new file is added.

We checked code completion is available in WebKit, Mozilla Firefox, and Google V8 by using this technique.

4.3. autopch

autopch is a GCC wrapper improving GCC's analyzing performance. It has been named because it applies precompiled header automatically. Using precompiled header, compilation performance will be improved notably. Especially, it is very important for a field such as code completion that requires high responsibility.

However, there is a big limitation in precompiled header. That is, translation unit can include only one precompiled header. It is main limitation of precompiled header, however, usually two or more headers will be included like:

test.cpp:

#include <iostream>
#include <string>
#include <vector>
int main() {...}

In such case, a technique making a header called stdafx.h that will precompiled is used.

stfafx.h:

#include <iostream>
#include <string>
#include <vector>

test.cpp:

#include <stdafx.h>
int main() {...}

Precompile:

$ # Only once
$ g++ stdafx.h

Compile:

$ g++ -c test.cpp

By this, compilation perfomance is actually improved, but it is too boring. This is a reason why use of precompiled header is not increased. autopch is a true tool for automating this boring instructions. It is easy to use. Just put autopch before gcc. Note that without -c option, autopch will not make a precompiled header.

$ autopch g++ -c test.cpp

First time to compile may be slow, but twice or later will be fast. Dependency files and actual precompiled headers are stored at ~/.autopch. Be careful to use autopch because precompiled header would be huge.

GCCSense uses autopch for improving code completion responsibility.

4.3.1. Benchmark

$ # no autopch
$ time g++ -fsyntax-only -c test.cpp
g++ -fsyntax-only -c test.cpp  4.49s user 0.19s system 95% cpu 4.915 total
$ # autpoch first time
$ time autopch g++ -fsyntax-only -c test.cpp
autopch g++ -fsyntax-only -c test.cpp  10.16s user 0.97s system 96% cpu 11.531 total
$ # autopch second time
$ time autopch g++ -fsyntax-only -c test.cpp
autopch g++ -fsyntax-only -c test.cpp  0.42s user 0.06s system 94% cpu 0.504 total
$ # autopch third time
time autopch g++ -fsyntax-only -c test.cpp
autopch g++ -fsyntax-only -c test.cpp  0.38s user 0.10s system 90% cpu 0.524 total

4.4. Editors

See installation for how to install an extension or plugin of individual editor. Remeber that to use code completion from editors, you need to record a compiler options with gccrec first. See gccrec for how to record. In a case that a source file can be compiled without any compile options, you don't need to record.

4.4.1. Emacs

Before use, please diagnose the installation was finished correctly with M-x gccsense-diagnose. A message "Everything OK!" will be showed in minibuffer if there is no problem. Please fix problems if you had errors or contact me if you can't resolve them.

To complete, do M-x gccsense-complete after . or ->. Code completion is not avaiable in a non existed file.

You can complete with M-x ac-complete-gccsense if you use Auto Complete Mode.

You may bind to C-c . like:

(add-hook 'c-mode-common-hook
          (lambda ()
            (local-set-key (kbd "C-c .") 'gccsense-complete)
            ;; or
            (local-set-key (kbd "C-c .") 'ac-complete-gccsense)))

You can use syntax-check with Flymake. It would be accurate and fast than original by using gccrec intead of Makefile. To use gccrec Flymake, do M-x gccsense-flymake-setup for each buffer. You may write the following code into your ~/.emacs.

(add-hook 'c-mode-common-hook
          (lambda ()
            (flymake-mode)
            (gccsense-flymake-setup)))

4.4.2. Vim

Before use, please diagnose the installation was finished correctly with :call GCCSenseDiagnose(). Please fix problems if you had errors or contact me if you can't resolve them.

To complete, do ^X ^U after . or ->. Code completion is not avaiable in a non existed file.

To complete with omni completion, set g:gccsenseUseOmniFunc to 1.

let g:gccsenseUseOmniFunc = 1

Now you can complete with ^X ^O.

5. Limitations

  • Objective-C and Java or else which is supported in GCC is not supported
  • Development assist is not supported in a code which can not be compiled with GCC 4.4
  • Development assist is not available in header files.

6. Trouble Shooting

6.1. Code completion doesn't work

Do diagnose. In Emacs, do M-x gccsense-diagnose. In Vim, do :call GCCSenseDiagnose(). If there is no problem, please make sure that the editing file is recorded with gccrec correctly.

$ gccrec -v -r a_problem_file.cpp

If you see "record not found", it means you don't yet record with gccrec. Please record with gccrec with refering to gccrec.

If you couldn't use code completion, please contact me.

 

 

 

 

 GCCSense 的用法看一下这个,这里就不赘述了--GCCSense 配置与用法

下面是几张配置好的贴图

这篇还有几张贴图

测试文件用的是OSG的库,一个做三维场景用的开源库

Emacs 自动补全的贴图

 

 

 

 

 

 

 

posted @ 2012-09-22 11:25  庚武  Views(838)  Comments(0Edit  收藏  举报