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.
-
A custom GCC that has functions such as code completion
-
A GCC wrapper for recording and replaying GCC command
-
A GCC wrapper for enabling precompiled header automatically
-
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的库,一个做三维场景用的开源库