2011年11月28日 星期一

boost Traverse directory

在看 Effective C++ 3rd 的時候,最後第55條寫 Familiarize yourself with boost.
其中簡述了 boost 的功能,我看到一項 Traverse file system 的功能。
這不正是我想要又常用的功能嗎?

於是搜尋了Google 找到以下網頁
http://stackoverflow.com/questions/2550309/traversing-a-directory

原始碼如下

#include 
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#define foreach BOOST_FOREACHnamespace fs = boost::filesystem;

fs::recursive_directory_iterator it(top), eod;
foreach (fs::path const & p, std::make_pair(it, eod)) {
    if (is_directory(p)) {
        ...
    } else if (is_regular_file(p)) {
        ...
    } else if (is_symlink(p)) {
        ...
    }
}
第二種寫法                                                                       using namespace boost::filesystem;
using namespace std;                                                                    path Path = "e:\\";
 for(recursive_directory_iterator it(Path); it != recursive_directory_iterator(); ++it)
 {
  if ( is_directory(*it) )
   cout << *it << it.level() << endl;
 }
然後開啟Visual Studio ,試著去編譯這個 boost 範例
1. 要 add include directory \boost_1_46_1\
2. 之後會出現無法 link libboost_filesystem-vc90-mt-gd-1_46_1.lib
這是因為沒有build boost lib
3. 有些boost library 需要build,使用 cmd prompt, 在 \boost_1_46_1\ 下,執行bootstrap
4. boostrap 會build bjam, 但是此處失敗了 因為include 不到 windows.h (因為Windows SDK 7沒裝完整 )。失敗原因從 bootstrap.log 中可以看出。重新執行Windows SDK setup 把Windows header 裝上,然後執行Windows SDK 下的Configuration Tool 設定好預設的SDK。
5. 設好了 include 後,之後 cannot open input file 'kernel32.lib', 所以 LIB 也要設置正確
6. 最後編譯成功後,會提示你 include 要加入 E:\boost_1_46_1, lib 要加入 E:\boost_1_46_1\stage\lib
7. 編譯過程中會出現一些Warning, 跟 D_SCL_SECURE_NO_DEPRECATE  有關, 詳情請google
(Visual Studio 2005 SP1以後 use _SCL_SECURE_NO_WARNINGS ) Standard C++ Library
_SCL_SECURE_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS
_AFX_SECURE_NO_WARNINGS
_ATL_SECURE_NO_WARNINGS
http://connect.microsoft.com/VisualStudio/feedback/details/101151/scl-secure-no-deprecate-is-not-found-by-search
Message: 'Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators''
正確解法要改用 Checked Iterators, and safe functions _s
http://msdn.microsoft.com/en-us/library/aa985872(v=VS.80).aspx

2011年11月7日 星期一

Build Cross Compiler GCC


1. Download
gcc 4.6.2
binutils 2.21.1a
gmp 5.0.2
mpfr 3.1.0
mpc 0.9
newlib 1.19



2. Build binutils
有 build system
     host sytem
     target system

The GNU autotools packages (i.e. autoconfautomake, and libtool) use the notion of a build platform, a host platform, and a target platform. The build platform is where the code is actually compiled. The host platform is where the compiled code will execute. The target platform usually only applies to compilers. It represents what type of object code the package itself will produce (such as cross-compiling a cross-compiler)



  1. build 就是你现在使用的机器。
  2. host 就是你编译好的程序能够运行的平台。
  3. target 编译程序能够处理的平台。一般都用在构建编译本身的时候(gcc), 才用target, 也就是说平时我们所说的交叉编译用不到target.

2.
參考這兩篇
3. 裝cygwin 1.7.9-1
default 之外還需要
-- dev
gcc-core
gcc-c++
make
-- interpreter
m4


4. build binutils
--target 不適用 用--build 和 --host  

要加 libiconv 不然會 make 失敗

5. build GMP
不能用 --target 要改用 --host 及 --build ( 沒有--build 會有warning)






Cross Compilation, --host=CPU-VENDOR-OS







When cross-compiling, the system used for compiling is given by `--build' and the system where the library will run is given by `--host'. For example when using a FreeBSD Athlon system to build GNU/Linux m68k binaries,
./configure --build=athlon-pc-freebsd3.5 --host=m68k-mac-linux-gnu
     
Compiler tools are sought first with the host system type as a prefix. For example m68k-mac-linux-gnu-ranlib is tried, then plain ranlib. This makes it possible for a set of cross-compiling tools to co-exist with native tools. The prefix is the argument to `--host', and this can be an alias, such as `m68k-linux'. But note that tools don't have to be setup this way, it's enough to just have a PATH with a suitable cross-compiling cc etc.
Compiling for a different CPU in the same family as the build system is a form of cross-compilation, though very possibly this would merely be special options on a native compiler. In any case `./configure' avoids depending on being able to run code on the build system, which is important when creating binaries for a newer CPU since they very possibly won't run on the build system.
In all cases the compiler must be able to produce an executable (of whatever format) from a standard C main. Although only object files will go to make up libgmp, `./configure' uses linking tests for various purposes, such as determining what functions are available on the host system.
Currently a warning is given unless an explicit `--build' is used when cross-compiling, because it may not be possible to correctly guess the build system type if the PATH has only a cross-compiling cc.
Note that the `--target' option is not appropriate for GMP. It's for use when building compiler tools, with `--host' being where they will run, and `--target' what they'll produce code for. Ordinary programs or libraries like GMP are only interested in the `--host' part, being where they'll run. (Some past versions of GMP used `--target' incorrectly.)


../gmp-5.0.2/configure --build=i686-cygwin --host=i686-cygwin --prefix=$PREFIX



6. build gcc
gcc 4.6.2 需要 GMP 4.2+, MPFR 2.3.1+, MPC 0.8.0+

1. build gcc 時可以下 make all-gcc 及 make all-install,如此只編譯 gcc,g++,其它的連結庫就不會去編譯,而造成一堆錯誤。
6. 如果只是要編 language c 則不需要 newlib,但是要有 c++ language 時,必需包含 newlib,而且需要 1.14.0,不要 1.15.0,編譯會過不了。


make all-gcc 後會有錯誤,沒有pod2man
這個要安裝 perl 才能解決


 --enable-languages=c,c++


build ARM-EABI 時沒問題
build MIPS-ELF 在 libstdc++ 時 會出現 No support for this host/target combination.
因為在 libstdc++ 下的 crossconfig.m4 沒有 support MIPS-ELF ( cygwin/mips-elf) ?


config.log 會有 configure 時的資訊


sde vs uclibc vs eglibc vs glibc




============================================




From Start
1. Download 
gcc 4.7.1
binutils 2.22
newlib 1.20
gmp 5.0.5
mpfr 3.1.0


2. binutils


make needs libiconv 


gmp
configure needs m4


mpfr

 ./configure --with-gmp=$PREFIX



3.

../gcc-4.1.1/configure --target=$TARGET --prefix=$PREFIX --without-headers --with-gmp=$PREFIX



use --enable-obsolete if compile arm-elf ....

4. When all done, compile booter
 出現 linker error
section .text.startup overlap with .data
這個問題好像是 gcc 4.6 以後會出現的 ( or binutils 2.21?)
通常 .data 的 linker script 是如下面這樣寫的
.data 0x81000000 :
  AT ( ADDR(.text) + SIZEOF(.text) )
但是好像後來又多出了一個 .text.startup section
所以 .data 就會跟 .text.startup 重疊 (開頭位置完全一樣)
所以最簡單且正確的改法是 再加上 .text.startup 的size
 .data 0x81000000 :
  AT ( ADDR(.text) + SIZEOF(.text) + SIZEOF(.text.startup) )

可以用 readelf , objdump 來看
http://www.linuxforums.org/articles/understanding-elf-using-readelf-and-objdump_125.html

5. 再來 build gdb 
需要裝 termcap

但是裝了 termcap 並沒有解決
再裝了 libncurses 也沒有解決
要裝 devel 目錄下的 libncursesw-devel 才 ok