Showing posts with label Cross compiler. Show all posts
Build application template script
Khi build một ứng dụng nào đó thì thường sẽ cần nhiều thư viện đi cùng, việc build từng lib đơn lẻ tỏ ra rất bất tiện khi ta cần build rất nhiều lib cùng một lúc, khi đó ta cần một script nào đó chỉ cần gõ một lệnh để build toàn bộ hệ thống.
Sau đây là một template đơn giản để ví dụ cho việc đó.
Link: https://github.com/eslinux/Utils/tree/master/build-app-template
Template for build app from list of library
#using command make.sh build make.sh clean component_name make.sh cleanall extpkgs -> lib that no need to download info -> flag to mask the lib that was downloaded/uncompressed/builded install -> app install dir patches -> patch file for lib script -> compile script of lib srcdir -> download && extract to this folder tools -> utility script make.sh -> main build script Makefile -> no using Readme.txt Info Flag: - .buildflag -> lib was builded - .unflag -> lib package was uncompress - .dlflag -> lib package was downloaded Before build you need to check some parameter in toos/Config file: - ROOTFS_DIR - TOOLCHAIN_DIR - CROSS - TOOLCHAIN_FILE (arm-toolchain.cmake) - PREFIX (default is install folder) - URL_SOURCE_DL Add library build script in make.sh - BASE_APPLIST Current example that build for 2 lib that is: opencv and zlib
Cross compiling the libraries
Bìa viết liên quan:
+ Cross compler
+ Makefile (Part 1)
+ Makefile (Part 2)
+ Cài đặt môi trường làm việc
1. Library configuration
Trong bài viết này hướng dẫn compile/cross compiling thư viện taglib-1.6.3 (thư viện có chức năng lấy thông tin meta-data của file nhạc) để minh họa cho dễ hiểu. Yêu cầu để thực hiện được phần này thì ít nhất phải biến cách sử dụng máy tính Linux Fedora, biết các command cơ bản trên terminal, biết phân quyền trong Linux, xem lại các bài viết trong mục Linux PC và Linux Basic nếu bạn chưa rõ.
Một số thuật ngữ:
+ Compile: compile thư viện cho host
+ Cross compiling: compile thư viện cho target (board nhúng), ở blog này sử dụng board nhúng Linux là FriendlyARM Mini2440
+ Build: tương đương với compile / cross compiling
Thư viện được cung cấp dưới dạng source code C/C++ và một shell script đi kèm có tên configure dùng để cài đặt các options phụ vụ cho việc build thư viện, file configure này có thể mở được bằng các text editor thông thường như gedit, geany. Sau khi cấu hình xong với configure thì sẽ thu được một Makefile, từ đó dùng lệnh make để build thư viện. Kết quả thu được sau khi build xong thư viện thường có cấu trúc thư mục như sau:
Để bắt đầu bạn download taglib-1.6.3 (có thể tải các version khác ngoài 1.6.3), sau đó giải nén, chuyển terminal vào thư mục taglib-1.6.3 vừa giải nén, chạy lệnh ./configure --help để xem hướng dẫn build thư viện:
./configure --help
1.1 Configuration
Các options để show thông tin về thư viện, ví dụ:
1.2 Installation directories
Thư mục để install thư viện vào đó:
hoặc
Nếu không cài đặt --prefix thì mặc định nó sẽ install vào thư mục /usr/local
--exec-prefix : mặc định được gán với PREFIX, giống với --prefix
1.3 Fine tuning of the installation directories
Các thư mục sẽ được tạo ra để chứa thư viện: bin, include, lib, etc, ...
Mặc định chúng sẽ là thư mục con của --prefix/PREFIX đã đươc đặt ở bước (2)
1.4 Program names
Không cần quan tâm
1.5 System types
Các options rất quan trong để compile cho host hoặc cross-compiling cho target (board nhúng), nếu bạn compile cho host, bạn không cần cài đặt các options này, nếu bạn cross-compiling cho target bạn cài đặt như sau:
hoặc
+ HOST
Là nơi mà chương trình sẽ chạy, trong ví dụ trên là board nhúng chạy chíp ARM
+BUILD
Là nơi mà chương trình compiler chạy, hoặc được build ra, ở đây là máy tính chạy chip Inter x86/64bits
+TARGET
Tương tự như HOST, thông số này không cần đặt
1.6 Optional Features
Các options có tiền tố --enable / --disable để cấu hình bật / tắt một tính năng nào đó của thư viện. Các tính năng này được cấu hình mặc định default=yes hoặc default=no ghi rõ trong phần chú thích, nhưng thông thường thì option thuộc dạng --enable thì mặc định là no, option dạng --disable thì mặc định là yes.
Ví dụ:
+ Tắt debug (default=yes)
+ Tắt warning (default=yes)
+ Không build thư viện static (default=no, cho thêm vào cho chắc :D)
+ Bật support MP4 (default=no)
Có rất nhiều options, bạn nên xem kỹ để lựa chọn enable/disable những options cần quan tâm, cái nào không quan tâm cứ để mặc định, thông thường bạn để tất cả chúng mặc định là đã ok rồi.
1.7 Optional Packages
Options này gần giống với --enable
1.8 Some influential environment variables
Ở đây là các biến môi trường sử dụng bởi compiler
+ CFLAGS / CXXFLAGS / CPPFLAGS
C/C++ compiler flags được pass vào cho compiler, bao gồm:
- Đường dẫn header file của thư viện phụ thuộc (nếu có), có dạng -I/path/to/include
Thư viện phụ thuộc: A là thư viện phụ thuộc của B nếu trong B có sử dụng các API do A cung cấp, vì thế A phải được build trước thì mới có thể build B được, vì thế -I/path/to/include có tác dụng cung cấp các API của A cho B trong quá trình compile ra object file.
- Các options riêng của compiler, ví dụ: -Wll, -g
+ CC / CXX / CPP
C compiler và C++ compiler
+ LDFLAGS
Linker flags, gồm các thông tin:
- Đường dẫn đến thư mục chứa thư viện phụ thuộc (.la, .so), có dạng -L/path/to/lib
- Các thư viện sẽ dùng, có dạng -l<name>; ví dụ: -ltag tương ứng với libtag
+ LIBS
Tương tự như phần "Các thư viện sẽ dùng" trong LDFLAGS, thông thường LIBS ít được dùng vì nó đã được bao hàm trong LDFLAGS
Ex:
hoặc
Note:
PATH: là biến môi trường chỉ ra đường dẫn đến file nhị phân của compiler
2. Compile taglib-1.6.3 for Linux Fedora x86_64
./configure: cấu hình mặc định, có chỉ ra thư mục để install, sau bước này sẽ có được Makefile
make
make install
tagreader_c.c (chương trình ví dụ có sử dụng thư viện taglib vừa build xong)
Makefile (Makefile cho ví dụ tagreader_c.c)
Make (Build application, cần có các biến môi trường để chỉ dẫn đến thư viện là PATH và LD_LIBRARY_PATH)
Execute (Cũng cần có biến môi trường như khi buil app)
3. Cross compiling taglib-1.6.3 for Friendlyarm mini2440
Phần build sẽ thực hiện trên máy tính (host), còn khi chạy chương trình thì trên board nhúng. Các command sẽ được biểu diễn ngắn gọn vì nó tương tự như trên mục 2.
Nếu bạn không có board nhúng thì bạn chỉ cần thực hiện xong bước build là ok rồi.
Trước hết, download toolchain cho board Friendlyarm Mini2440 arm-linux-gcc; giải nén, copy thư mục FriendlyARM vào thư mục /opt.
Build taglib (on Host)
tagreader_c.c (như mục 2)
Makefile
Build application (on Host)
Execute application (on board - Friendlyarm mini2440)
Để thực hiện được bước này, bạn cần biết cách setup board Mini2440 kết nối với máy tính như thế nào, điều khiển board qua chương trình minicom, bước này chỉ có ý nghĩ khi bạn đã xem các hướng dẫn trong phần FriendlyARM, nếu bạn chưa biết thì tạm thời tạm không thực hiện bước này.
Copy toàn bộ thư viện, file app, file nhạc để test vào thư mục taglib trên SDCARD. Khi Mini2440 hoạt động, SDCARD sẽ được mount vào thư mục /sdcard, vì vậy thư mục taglib trên SDCARD sẽ có đường dẫn là /sdcard/taglib
Note: Biến môi trường PATH và LD_LIBRARY_PATH là cực kỳ quan trọng, chúng luôn phải được sử dụng trong tất cả các quá trình từ build library, build application đến khi execute chương trình.
+ Cross compler
+ Makefile (Part 1)
+ Makefile (Part 2)
+ Cài đặt môi trường làm việc
1. Library configuration
Trong bài viết này hướng dẫn compile/cross compiling thư viện taglib-1.6.3 (thư viện có chức năng lấy thông tin meta-data của file nhạc) để minh họa cho dễ hiểu. Yêu cầu để thực hiện được phần này thì ít nhất phải biến cách sử dụng máy tính Linux Fedora, biết các command cơ bản trên terminal, biết phân quyền trong Linux, xem lại các bài viết trong mục Linux PC và Linux Basic nếu bạn chưa rõ.
Một số thuật ngữ:
+ Compile: compile thư viện cho host
+ Cross compiling: compile thư viện cho target (board nhúng), ở blog này sử dụng board nhúng Linux là FriendlyARM Mini2440
+ Build: tương đương với compile / cross compiling
Thư viện được cung cấp dưới dạng source code C/C++ và một shell script đi kèm có tên configure dùng để cài đặt các options phụ vụ cho việc build thư viện, file configure này có thể mở được bằng các text editor thông thường như gedit, geany. Sau khi cấu hình xong với configure thì sẽ thu được một Makefile, từ đó dùng lệnh make để build thư viện. Kết quả thu được sau khi build xong thư viện thường có cấu trúc thư mục như sau:
bin #chứa các file execute nhị phân (tương tự file .exe bên Windows)
etc #chứa các file cấu hình (vd: file.conf)
include #chứa các file header để include vào các chương trình
có sử dụng thư viện này (vd: tag.h)
lib #chứa các file thư viện tĩnh/động .la/.so, cùng với header file để phục vụ
cho các chương trình khác có sử dụng thư viện này (vd: libtag.la, libtag.so)
man #chứa các file tài liệu / hướng dẫn sử dụng dạng text
share #chứa nhiều loại file như hướng dẫn / script / media, ...
...
Để bắt đầu bạn download taglib-1.6.3 (có thể tải các version khác ngoài 1.6.3), sau đó giải nén, chuyển terminal vào thư mục taglib-1.6.3 vừa giải nén, chạy lệnh ./configure --help để xem hướng dẫn build thư viện:
./configure --help
[ninhld@localhost taglib-1.6.3]$ ./configure --help
`configure' configures this package to adapt to many kinds of systems.
Usage: ./configure [OPTION]... [VAR=VALUE]...
To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE. See below for descriptions of some of the useful variables.
Defaults for the options are specified in brackets.
Configuration: (1)
-h, --help display this help and exit
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
-q, --quiet, --silent do not print `checking...' messages
--cache-file=FILE cache test results in FILE [disabled]
-C, --config-cache alias for `--cache-file=config.cache'
-n, --no-create do not create output files
--srcdir=DIR find the sources in DIR [configure dir or `..']
Installation directories: (2)
--prefix=PREFIX install architecture-independent files in PREFIX
[/usr/local]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[PREFIX]
By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc. You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.
For better control, use the options below.
Fine tuning of the installation directories: (3)
--bindir=DIR user executables [EPREFIX/bin]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--libexecdir=DIR program executables [EPREFIX/libexec]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
--datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
--datadir=DIR read-only architecture-independent data [DATAROOTDIR]
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
--docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
--psdir=DIR ps documentation [DOCDIR]
Program names: (4)
--program-prefix=PREFIX prepend PREFIX to installed program names
--program-suffix=SUFFIX append SUFFIX to installed program names
--program-transform-name=PROGRAM run sed PROGRAM on installed program names
System types: (*5)
--build=BUILD configure for building on BUILD [guessed]
--host=HOST cross-compile to build programs to run on HOST [BUILD]
--target=TARGET configure for building compilers for TARGET [HOST]
Optional Features: (6)
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-fast-perl disable fast Makefile generation (needs perl)
--enable-debug=ARG enables debug symbols (yes|no|full) default=no
--disable-debug disables debug output and debug symbols default=no
--enable-strict compiles with strict compiler options (may not
work!)
--disable-warnings disables compilation with -Wall and similar
--enable-profile creates profiling infos default=no
--disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors
--enable-pch enables precompiled header support (currently only
KCC or gcc >=3.4+unsermake) default=no
--enable-coverage use gcc coverage testing
--enable-new-ldflags enable the new linker flags
--enable-final build size optimized apps (experimental - needs lots
of memory)
--enable-closure delay template instantiation
--enable-nmcheck enable automatic namespace cleanness check
--enable-shared[=PKGS] build shared libraries [default=yes]
--enable-static[=PKGS] build static libraries [default=no]
--enable-libsuffix /lib directory suffix (64,32,none,auto=default)
--enable-fast-install[=PKGS]
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
--enable-mp4 add MP4 support
--enable-asf add ASF support
Optional Packages: (7)
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
--with-pic try to use only PIC/non-PIC objects [default=use
both]
--with-tags[=TAGS] include additional configurations [automatic]
Some influential environment variables: (*8)
CC C compiler command
CFLAGS C compiler flags
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
nonstandard directory <lib dir>
LIBS libraries to pass to the linker, e.g. -l<library>
CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
you have headers in a nonstandard directory <include dir>
CPP C preprocessor
CXX C++ compiler command
CXXFLAGS C++ compiler flags
CXXCPP C++ preprocessor
F77 Fortran 77 compiler command
FFLAGS Fortran 77 compiler flags
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
[ninhld@localhost taglib-1.6.3]$
1.1 Configuration
Các options để show thông tin về thư viện, ví dụ:
configure --help hoặc configure -h
configure --version hoặc configure -V
1.2 Installation directories
Thư mục để install thư viện vào đó:
export PREFIX=/home/ninhld/Documents/taglib_install #export biến môi trường
./configure --prefix=$PREFIX
hoặc
./configure --prefix=/home/ninhld/Documents/taglib_install
Nếu không cài đặt --prefix thì mặc định nó sẽ install vào thư mục /usr/local
--exec-prefix : mặc định được gán với PREFIX, giống với --prefix
1.3 Fine tuning of the installation directories
--bindir=DIR user executables [EPREFIX/bin]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--libexecdir=DIR program executables [EPREFIX/libexec]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
...
Các thư mục sẽ được tạo ra để chứa thư viện: bin, include, lib, etc, ...
Mặc định chúng sẽ là thư mục con của --prefix/PREFIX đã đươc đặt ở bước (2)
1.4 Program names
Không cần quan tâm
1.5 System types
Các options rất quan trong để compile cho host hoặc cross-compiling cho target (board nhúng), nếu bạn compile cho host, bạn không cần cài đặt các options này, nếu bạn cross-compiling cho target bạn cài đặt như sau:
export HOST=arm-none-linux-gnueabi
export BUILD=x86_64
./configure --build=${BUILD} --host=${HOST}
hoặc
./configure --build=x86_64 --host=arm-none-linux-gnueabi
+ HOST
Là nơi mà chương trình sẽ chạy, trong ví dụ trên là board nhúng chạy chíp ARM
+BUILD
Là nơi mà chương trình compiler chạy, hoặc được build ra, ở đây là máy tính chạy chip Inter x86/64bits
+TARGET
Tương tự như HOST, thông số này không cần đặt
1.6 Optional Features
Các options có tiền tố --enable / --disable để cấu hình bật / tắt một tính năng nào đó của thư viện. Các tính năng này được cấu hình mặc định default=yes hoặc default=no ghi rõ trong phần chú thích, nhưng thông thường thì option thuộc dạng --enable thì mặc định là no, option dạng --disable thì mặc định là yes.
Ví dụ:
./configure --disable-debug --disable-warnings --enable-static=no --enable-mp4
+ Tắt debug (default=yes)
+ Tắt warning (default=yes)
+ Không build thư viện static (default=no, cho thêm vào cho chắc :D)
+ Bật support MP4 (default=no)
Có rất nhiều options, bạn nên xem kỹ để lựa chọn enable/disable những options cần quan tâm, cái nào không quan tâm cứ để mặc định, thông thường bạn để tất cả chúng mặc định là đã ok rồi.
1.7 Optional Packages
Options này gần giống với --enable
1.8 Some influential environment variables
Ở đây là các biến môi trường sử dụng bởi compiler
+ CFLAGS / CXXFLAGS / CPPFLAGS
C/C++ compiler flags được pass vào cho compiler, bao gồm:
- Đường dẫn header file của thư viện phụ thuộc (nếu có), có dạng -I/path/to/include
Thư viện phụ thuộc: A là thư viện phụ thuộc của B nếu trong B có sử dụng các API do A cung cấp, vì thế A phải được build trước thì mới có thể build B được, vì thế -I/path/to/include có tác dụng cung cấp các API của A cho B trong quá trình compile ra object file.
- Các options riêng của compiler, ví dụ: -Wll, -g
+ CC / CXX / CPP
C compiler và C++ compiler
#x86
CC=gcc
CXX=g++
CPP=g++
hoặc
#arm
CC=arm-none-linux-gnueabi-gcc
CXX=arm-none-linux-gnueabi-g++
CPP=arm-none-linux-gnueabi-g++
+ LDFLAGS
Linker flags, gồm các thông tin:
- Đường dẫn đến thư mục chứa thư viện phụ thuộc (.la, .so), có dạng -L/path/to/lib
- Các thư viện sẽ dùng, có dạng -l<name>; ví dụ: -ltag tương ứng với libtag
+ LIBS
Tương tự như phần "Các thư viện sẽ dùng" trong LDFLAGS, thông thường LIBS ít được dùng vì nó đã được bao hàm trong LDFLAGS
Ex:
#export biến môi trường
export CC_PATH=/opt/FriendlyARM/toolschain/4.4.3
export CROSS_COMPILE=${CC_PATH}/bin/arm-none-linux-gnueabi-
export PATH=$PATH:${CC_PATH}/bin
export CC=${CROSS_COMPILE}gcc
export CXX=${CROSS_COMPILE}g++
export CFLAGS+="-I/friendlyarm/usr/local/include -DDEBUG -Wall -g"
export CXXFLAGS=$CFLAGS
export LDFLAGS+="-L/friendlyarm/usr/local/lib -lm"
./configure
hoặc
export CC_PATH=/opt/FriendlyARM/toolschain/4.4.3
export CROSS_COMPILE=${CC_PATH}/bin/arm-none-linux-gnueabi-
export PATH=$PATH:${CC_PATH}/bin
#nhúng các flags vào thẳng configure
./configure CC=${CROSS_COMPILE}gcc CXX=${CROSS_COMPILE}g++ \
CFLAGS="-I/friendlyarm/usr/local/include -Wall -g" \
CXXFLAGS=$CFLAGS LDFLAGS="-L/friendlyarm/usr/local/lib -lm"
Note:
PATH: là biến môi trường chỉ ra đường dẫn đến file nhị phân của compiler
2. Compile taglib-1.6.3 for Linux Fedora x86_64
./configure: cấu hình mặc định, có chỉ ra thư mục để install, sau bước này sẽ có được Makefile
[ninhld@localhost taglib-1.6.3]$
[ninhld@localhost taglib-1.6.3]$ export PREFIX=/home/ninhld/Documents/taglib_install
[ninhld@localhost taglib-1.6.3]$ ./configure --prefix=$PREFIX
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
...
...
config.status: creating Makefile
config.status: creating bindings/Makefile
config.status: creating bindings/c/Makefile
config.status: creating examples/Makefile
config.status: creating taglib/Makefile
config.status: creating taglib/ape/Makefile
config.status: creating taglib/asf/Makefile
config.status: creating taglib/flac/Makefile
config.status: creating taglib/mp4/Makefile
config.status: creating taglib/mpc/Makefile
config.status: creating taglib/mpeg/Makefile
config.status: creating taglib/mpeg/id3v1/Makefile
config.status: creating taglib/mpeg/id3v2/Makefile
config.status: creating taglib/mpeg/id3v2/frames/Makefile
config.status: creating taglib/ogg/Makefile
config.status: creating taglib/ogg/flac/Makefile
config.status: creating taglib/ogg/speex/Makefile
config.status: creating taglib/ogg/vorbis/Makefile
config.status: creating taglib/riff/Makefile
config.status: creating taglib/riff/aiff/Makefile
config.status: creating taglib/riff/wav/Makefile
config.status: creating taglib/toolkit/Makefile
config.status: creating taglib/trueaudio/Makefile
config.status: creating taglib/wavpack/Makefile
config.status: creating tests/Makefile
config.status: creating taglib-config
config.status: creating taglib.pc
config.status: creating bindings/c/taglib_c.pc
config.status: creating config.h
config.status: creating taglib/taglib_config.h
config.status: executing depfiles commands
Good - your configure finished. Start make now
[ninhld@localhost taglib-1.6.3]$
make
[ninhld@localhost taglib-1.6.3]$
[ninhld@localhost taglib-1.6.3]$ make
make all-recursive
make[1]: Entering directory `/home/ninhld/Documents/taglib-1.6.3'
Making all in taglib
make[2]: Entering directory `/home/ninhld/Documents/taglib-1.6.3/taglib'
make all-recursive
make[3]: Entering directory `/home/ninhld/Documents/taglib-1.6.3/taglib'
Making all in toolkit
make[4]: Entering directory `/home/ninhld/Documents/taglib-1.6.3/taglib/toolkit'
/bin/sh ../../libtool --silent --tag=CXX --mode=compile g++ -DMAKE_TAGLIB_LIB -DHAVE_CONFIG_H -I. -I../.. -I../../taglib -I../../taglib -O2 -fno-exceptions -fno-check-new -fno-common -fexceptions -MT tstring.lo -MD -MP -MF .deps/tstring.Tpo -c -o tstring.lo tstring.cpp
..
...
make[3]: Leaving directory `/home/ninhld/Documents/taglib-1.6.3/bindings/c'
make[3]: Entering directory `/home/ninhld/Documents/taglib-1.6.3/bindings'
make[3]: Nothing to be done for `all-am'.
make[3]: Leaving directory `/home/ninhld/Documents/taglib-1.6.3/bindings'
make[2]: Leaving directory `/home/ninhld/Documents/taglib-1.6.3/bindings'
Making all in tests
make[2]: Entering directory `/home/ninhld/Documents/taglib-1.6.3/tests'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/home/ninhld/Documents/taglib-1.6.3/tests'
make[2]: Entering directory `/home/ninhld/Documents/taglib-1.6.3'
make[2]: Leaving directory `/home/ninhld/Documents/taglib-1.6.3'
make[1]: Leaving directory `/home/ninhld/Documents/taglib-1.6.3'
[ninhld@localhost taglib-1.6.3]$
[ninhld@localhost taglib-1.6.3]$
make install
[ninhld@localhost taglib-1.6.3]$ make install
Making install in taglib
make[1]: Entering directory `/home/ninhld/Documents/taglib-1.6.3/taglib'
Making install in toolkit
make[2]: Entering directory `/home/ninhld/Documents/taglib-1.6.3/taglib/toolkit'
make[3]: Entering directory `/home/ninhld/Documents/taglib-1.6.3/taglib/toolkit'
make[3]: Nothing to be done for `install-exec-am'.
test -z "/home/ninhld/Documents/taglib_install/include/taglib" || /usr/bin/mkdir -p "/home/ninhld/Documents/taglib_install/include/taglib"
/usr/bin/install -c -p -m 644 'taglib.h' '/home/ninhld/Documents/taglib_install/include/taglib/taglib.h'
/usr/bin/install -c -p -m 644 'tstring.h' '/home/ninhld/Documents/taglib_install/include/taglib/tstring.h'
/usr/bin/install -c -p -m 644 'tlist.h' '/home/ninhld/Documents/taglib_install/include/taglib/tlist.h'
/usr/bin/install -c -p -m 644 'tlist.tcc' '/home/ninhld/Documents/taglib_install/include/taglib/tlist.tcc'
/usr/bin/install -c -p -m 644 'tstringlist.h' '/home/ninhld/Documents/taglib_install/include/taglib/tstringlist.h'
/usr/bin/install -c -p -m 644 'tbytevector.h' '/home/ninhld/Documents/taglib_install/include/taglib/tbytevector.h'
/usr/bin/install -c -p -m 644 'tbytevectorlist.h' '/home/ninhld/Documents/taglib_install/include/taglib/tbytevectorlist.h'
/usr/bin/install -c -p -m 644 'tfile.h' '/home/ninhld/Documents/taglib_install/include/taglib/tfile.h'
/usr/bin/install -c -p -m 644 'tmap.h' '/home/ninhld/Documents/taglib_install/include/taglib/tmap.h'
/usr/bin/install -c -p -m 644 'tmap.tcc' '/home/ninhld/Documents/taglib_install/include/taglib/tmap.tcc'
make[3]: Leaving directory `/home/ninhld/Documents/taglib-1.6.3/taglib/toolkit'
make[2]: Leaving directory `/home/ninhld/Documents/taglib-1.6.3/taglib/toolkit'
Making install in mpeg
...
...
/usr/bin/install -c -p -m 644 'taglib.pc' '/home/ninhld/Documents/taglib_install/lib64/pkgconfig/taglib.pc'
make[2]: Leaving directory `/home/ninhld/Documents/taglib-1.6.3'
make[1]: Leaving directory `/home/ninhld/Documents/taglib-1.6.3'
[ninhld@localhost taglib-1.6.3]$
tagreader_c.c (chương trình ví dụ có sử dụng thư viện taglib vừa build xong)
/* Copyright (C) 2003 Scott Wheeler <wheeler@kde.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <tag_c.h>
#ifndef FALSE
#define FALSE 0
#endif
int main(int argc, char *argv[])
{
int i;
int seconds;
int minutes;
TagLib_File *file;
TagLib_Tag *tag;
const TagLib_AudioProperties *properties;
taglib_set_strings_unicode(FALSE);
for(i = 1; i < argc; i++) {
printf("******************** \"%s\" ********************\n", argv[i]);
file = taglib_file_new(argv[i]);
if(file == NULL)
break;
tag = taglib_file_tag(file);
properties = taglib_file_audioproperties(file);
if(tag != NULL) {
printf("-- TAG --\n");
printf("title - \"%s\"\n", taglib_tag_title(tag));
printf("artist - \"%s\"\n", taglib_tag_artist(tag));
printf("album - \"%s\"\n", taglib_tag_album(tag));
printf("year - \"%i\"\n", taglib_tag_year(tag));
printf("comment - \"%s\"\n", taglib_tag_comment(tag));
printf("track - \"%i\"\n", taglib_tag_track(tag));
printf("genre - \"%s\"\n", taglib_tag_genre(tag));
}
if(properties != NULL) {
seconds = taglib_audioproperties_length(properties) % 60;
minutes = (taglib_audioproperties_length(properties) - seconds) / 60;
printf("-- AUDIO --\n");
printf("bitrate - %i\n", taglib_audioproperties_bitrate(properties));
printf("sample rate - %i\n", taglib_audioproperties_samplerate(properties));
printf("channels - %i\n", taglib_audioproperties_channels(properties));
printf("length - %i:%02i\n", minutes, seconds);
}
taglib_tag_free_strings();
taglib_file_free(file);
}
return 0;
}
Makefile (Makefile cho ví dụ tagreader_c.c)
.PHONY: all, install, clean
TARGET:=tagreader
HDRS+=
CSRCS+= tagreader_c.c
CPPSRCS+=
OBJSDIR=./build
OBJS:= $(patsubst %.cpp, $(OBJSDIR)/%.o, $(CPPSRCS))
OBJS+= $(patsubst %.c, $(OBJSDIR)/%.o, $(CSRCS))
INCDIR+= -I/home/ninhld/Documents/taglib_install/include \
-I/home/ninhld/Documents/taglib_install/include/taglib
CFLAGS += -DDEBUG -Wall -g
LDFLAGS += -L/home/ninhld/Documents/taglib_install/lib64 -ltag -ltag_c
CC:= gcc
CXX:= g++
all: ${TARGET}
${TARGET} : $(OBJS)
@echo " [LINK] $@"
@mkdir -p $(shell dirname $@)
@$(CXX) $(OBJS) -o $@ $(LDFLAGS)
$(OBJSDIR)/%.o: %.c $(HDRS)
@echo " [CC] $@"
@mkdir -p $(shell dirname $@)
@$(CC) -c $< -o $@ $(CFLAGS) ${INCDIR}
$(OBJSDIR)/%.o: %.cpp $(HDRS)
@echo " [CXX] $@"
@mkdir -p $(shell dirname $@)
@$(CXX) -c $< -o $@ $(CFLAGS) ${INCDIR}
install:
cp -rf ${TARGET} /usr/local/bin
clean:
rm -rf ${OBJSDIR}
rm -rf ${TARGET}
Make (Build application, cần có các biến môi trường để chỉ dẫn đến thư viện là PATH và LD_LIBRARY_PATH)
[ninhld@localhost examples]$
[ninhld@localhost examples]$ export TAGLIBDIR=/home/ninhld/Documents/taglib_install
[ninhld@localhost examples]$ export PATH=$PATH:${TAGLIBDIR}/bin
[ninhld@localhost examples]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${TAGLIBDIR}/lib64
[ninhld@localhost examples]$
[ninhld@localhost examples]$
[ninhld@localhost examples]$ make
[CC] build/tagreader_c.o
[LINK] tagreader
[ninhld@localhost examples]$
[ninhld@localhost examples]$ ldd tagreader #kiểm tra các lib được dùng trong chương trình
linux-vdso.so.1 => (0x00007fff7a8af000)
libtag.so.1 => /home/ninhld/Documents/taglib_install/lib64/libtag.so.1 (0x00007f72c4eb6000)
libtag_c.so.0 => /home/ninhld/Documents/taglib_install/lib64/libtag_c.so.0 (0x00007f72c4cb0000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000003839a00000)
libm.so.6 => /lib64/libm.so.6 (0x000000382ae00000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000382ca00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003829e00000)
libz.so.1 => /lib64/libz.so.1 (0x000000382a600000)
/lib64/ld-linux-x86-64.so.2 (0x0000003829600000)
[ninhld@localhost examples]$
[ninhld@localhost examples]$
Execute (Cũng cần có biến môi trường như khi buil app)
[ninhld@localhost examples]$ export TAGLIBDIR=/home/ninhld/Documents/taglib_install
[ninhld@localhost examples]$ export PATH=$PATH:${TAGLIBDIR}/bin
[ninhld@localhost examples]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${TAGLIBDIR}/lib64
[ninhld@localhost examples]$
[ninhld@localhost examples]$ ./tagreader /home/ninhld/Music/hanh_phuc_neu_co_em.mp3
******************** "/home/ninhld/Music/hanh_phuc_neu_co_em.mp3" ********************
-- TAG --
title - "Hạnh Phúc Nếu Anh Có Em "
artist - "Phúc bồ "
album - "mp3.zing.vn"
year - "0"
comment - "Zing MP3 - Dinh cao am nhac"
track - "0"
genre - ""
-- AUDIO --
bitrate - 128
sample rate - 44100
channels - 2
length - 3:05
[ninhld@localhost examples]$
3. Cross compiling taglib-1.6.3 for Friendlyarm mini2440
Phần build sẽ thực hiện trên máy tính (host), còn khi chạy chương trình thì trên board nhúng. Các command sẽ được biểu diễn ngắn gọn vì nó tương tự như trên mục 2.
Nếu bạn không có board nhúng thì bạn chỉ cần thực hiện xong bước build là ok rồi.
Trước hết, download toolchain cho board Friendlyarm Mini2440 arm-linux-gcc; giải nén, copy thư mục FriendlyARM vào thư mục /opt.
Build taglib (on Host)
export CC_PATH=/opt/FriendlyARM/toolschain/4.4.3
export PATH=$PATH:${CC_PATH}/bin
export CROSS_COMPILE=${CC_PATH}/bin/arm-none-linux-gnueabi-
export CC=${CROSS_COMPILE}gcc
export HOST=arm-none-linux-gnueabi
export BUILD=x86_64
export PREFIX=/home/ninhld/Documents/taglib_install_target
./configure --prefix=$PREFIX --build=${BUILD} --host=${HOST}
make
make install
tagreader_c.c (như mục 2)
Makefile
.PHONY: all, install, clean
TARGET:=tagreader
HDRS+=
CSRCS+= tagreader_c.c
CPPSRCS+=
OBJSDIR=./build
OBJS:= $(patsubst %.cpp, $(OBJSDIR)/%.o, $(CPPSRCS))
OBJS+= $(patsubst %.c, $(OBJSDIR)/%.o, $(CSRCS))
INCDIR+= -I/home/ninhld/Documents/taglib_install_target/include \
-I/home/ninhld/Documents/taglib_install_target/include/taglib
CFLAGS += -DDEBUG -Wall -g
LDFLAGS += -L/home/ninhld/Documents/taglib_install_target/lib -ltag -ltag_c
CC=${CROSS_COMPILE}gcc
CXX=${CROSS_COMPILE}g++
all: ${TARGET}
${TARGET} : $(OBJS)
@echo " [LINK] $@"
@mkdir -p $(shell dirname $@)
@$(CXX) $(OBJS) -o $@ $(LDFLAGS)
$(OBJSDIR)/%.o: %.c $(HDRS)
@echo " [CC] $@"
@mkdir -p $(shell dirname $@)
@$(CC) -c $< -o $@ $(CFLAGS) ${INCDIR}
$(OBJSDIR)/%.o: %.cpp $(HDRS)
@echo " [CXX] $@"
@mkdir -p $(shell dirname $@)
@$(CXX) -c $< -o $@ $(CFLAGS) ${INCDIR}
install:
cp -rf ${TARGET} /usr/local/bin
clean:
rm -rf ${OBJSDIR}
rm -rf ${TARGET}
Build application (on Host)
export TAGLIBDIR=/home/ninhld/Documents/taglib_install_target
export PATH=$PATH:${TAGLIBDIR}/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${TAGLIBDIR}/lib
make
Execute application (on board - Friendlyarm mini2440)
Để thực hiện được bước này, bạn cần biết cách setup board Mini2440 kết nối với máy tính như thế nào, điều khiển board qua chương trình minicom, bước này chỉ có ý nghĩ khi bạn đã xem các hướng dẫn trong phần FriendlyARM, nếu bạn chưa biết thì tạm thời tạm không thực hiện bước này.
Copy toàn bộ thư viện, file app, file nhạc để test vào thư mục taglib trên SDCARD. Khi Mini2440 hoạt động, SDCARD sẽ được mount vào thư mục /sdcard, vì vậy thư mục taglib trên SDCARD sẽ có đường dẫn là /sdcard/taglib
export TAGLIBDIR=/sdcard/taglib
export PATH=$PATH:${TAGLIBDIR}/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${TAGLIBDIR}/lib
cd /sdcard/taglib
./tagreader /sdcard/taglib/hanh_phuc_neu_co_em.mp3
******************** "/sdcard/taglib/hanh_phuc_neu_co_em.mp3" ********************
-- TAG --
title - "H�á�º�¡nh Ph�Ã�ºc N�á�º�¿u Anh C�Ã�³ Em "
artist - "Ph�Ã�ºc b�á�»��“ "
album - "mp3.zing.vn"
year - "0"
comment - "Zing MP3 - Dinh cao am nhac"
track - "0"
genre - ""
-- AUDIO --
bitrate - 128
sample rate - 44100
channels - 2
length - 3:05
Note: Biến môi trường PATH và LD_LIBRARY_PATH là cực kỳ quan trọng, chúng luôn phải được sử dụng trong tất cả các quá trình từ build library, build application đến khi execute chương trình.
Cross Compiler
1. Định nghĩa trình biên dịch Compiler
Trình biên dịch, còn gọi là phần mềm biên dịch, compiler, là một chương trình máy tính làm công việc dịch một chuỗi các câu lệnh được viết bằng một ngôn ngữ lập trình (gọi là ngôn ngữ nguồn hay mã nguồn), thành một chương trình tương đương nhưng ở dưới dạng một ngôn ngữ máy tính mới (gọi là ngôn ngữ đích) và thường là ngôn ngữ ở cấp thấp hơn, như ngôn ngữ máy. Chương trình mới được dịch này gọi mã đối tượng. [trích dẫn]2. Quá trình biên dịch
Sơ đồ đơn giản
Ví dụ có chương trình sau được lưu dưới tên mytest.c
#include <stdio.h>
#include <math.h>
#define PI 3.14
int main(int argc, char **argv)
{
float x, y;
x = PI / 3;
y = cos(x);
printf("gia tri cos(%f) = %f \n", x, y);
return 1;
}
Trong chương trình có sử dụng thư viện toán học math cho hàm cos(x), vậy trong quá trình Linker sẽ tiến hành lấy mã của hàm printf() trong thư viện để kết hợp với mã thông thường khác.
Sơ đồ chi tiết từ Code/Build/Run
3. Cross Compiler /Toolchain là gì
Cross Compiler hay còn gọi là Toolchain được định nghĩa:
A cross compiler is a compiler capable of creating executable code for a platform other than the one on which the compiler is running. For example, a compiler that runs on a Windows 7 PC but generates code that runs on Android smartphone is a cross compiler
Có nghĩa là source code được viết trên máy tính chạy chíp Intel (x86 platform), thông qua một cross compiler sẽ cho ra file nhị phân (mã máy) có khả năng chạy được trên một nên tảng chip khác là ARM (ARM platform). Trên hình native compiler là trình biên dịch để tạo ra file nhị phân chạy trên chính máy tính đang dùng để viết source code.
4. Hệ thống Cross Compiler
Quá trình tạo ra và sử dụng tool chain liên quan đến 3 đối tượng:
+ Build : là hệ thống/platform tạo ra tool chain, thường là các máy tính chạy nền tảng chip Intel x86, x84_64 chạy hệ điều hành Linux hoặc Windows.
+ Host: là hệ thống chạy chương trình tool chain để compile source của một chương trình ứng dụng nào đó, host cũng giống như Build, thường là các máy tính Intel chạy Linux hoặc Windows OS
+ Target: là hệ thống chạy các chương trình (dưới dạng file nhị phân - mã máy) do hệ thống Host tạo ra, target thường là các hệ thống nhúng chạy chip ARM, MIPS, PowerPC, ...; tuy nhiên target cũng có thể là một máy tính bình thường chạy chip Intel.
VD:
BUILD=x86
HOST=x86
TARGTE=arm-linux
5. Các thành phần của compiler
+ Binutils
Là một tập các công cụ để tạo và quản lý file nhị phân (bin) của target CPU
as : là assembler, nó sinh ra mã nhị phân (binary code) từ assembler source code
ld : trình liên kết (linker)
ar, ranlib : sinh ra file nén .a, sử dụng như là thư viện
objdump, readelf, size, nm, strings: phân tích file nhị phân
strip : để loại bỏ những phần thừa trong file nhị phân để giảm kích thước của chúng
Thông thường để cross-compiler một chương trình ta phải cài đặt biến môi trường mới có thể compile đúng được
export PATH=/path/to/compiler/bin:$PATH #đường dẫn đến thư mục chứa as, ld, ...
export CROSS_COMPILE=arm-none-linux-gnueabi-
export CC=${CROSS_COMPILE}gcc
export CXX=${CROSS_COMPILE}g++
export CPP=${CROSS_COMPILE}cpp
export AR=${CROSS_COMPILE}ar
export AS=${CROSS_COMPILE}as
export LD=${CROSS_COMPILE}ld
export RANLIB=${CROSS_COMPILE}ranlib
export STRIP=${CROSS_COMPILE}strip
+ C/C++ Library
Library được dùng làm interface giữa applications và kernel, cung cấp các C API chuẩn để dễ dàng phát triển ứng dụng. Một số libb có thể kể đến như: glibc, uClibc, eglibc, dietlibc, newlib, ...
+ Kernel header
Kernel header cần thiết cho Applications và C Library để cung cấp các API giao tiếp với Kernel.
+ GCC compiler
gcc, c++, g++ : compiler
Trình biên dịch trong hệ thống Linux, compile cho rất nhiều ngôn ngữ và nhiều kiến trúc CPU khác nhau như ARM, MIPS, PowerPC, SuperH, x86; tuy nhiên trong blog này chỉ đề cập đến ngôn ngữ C/C++ và kiến trúc CPU là ARM và x86.
+ GDB Debugger
Trình gỡ rối, trợ giúp cho quá trình phát hiện lỗi khi develop application.
6. Cài đặt GCC
Trong blog này đề cập đến GCC Compiler (gcc trên host-x86 và cross gcc cho target-ARM), các compiler được các hãng sản xuất chip làm ra và phân phối đến các khách hàng thông qua website của hãng.
Một số dòng chip phổ biến dựa trên kiến trúc ARM hay MIPS thường dễ dàng có được cross-compiler trên một số nhà cung cấp miễn phí như Sourcery hay Linaro.
GCC chia compiler ra làm 2 phần, gcc là compiler cho C source và g++ cho C++ source, tuy nhiên cũng có thể g++ để compile C source bình thường.
Trên Fedora bạn có thể cài đặt compiler thông qua lệnh sau:
yum install gcc g++Tham khảo thêm mục Linux Development tại đây.
Xét ví dụ:
main.c / main.cpp
#include <stdio.h>
#include <math.h>
int main(int argc, char **argv){
double x;
x = sqrt(4);
printf("x = %f \n", x);
return 1;
}
Terminal command:
$export CFLAGS="-I./include -DDEBUG -Wall -g"
$export LDFLAGS+=" -L./lib -lm"
$gcc -c main.c ${CFLAGS} #tạo file object từ source
$gcc -o prog main.o ${LDFLAGS} #tạo file chương trình nhị phân từ file object
hoặc
$export CXXFLAGS="-I./include -DDEBUG -Wall -g"
$export LDFLAGS+=" -L./lib -lm"
$g++ -c main.cpp ${CXXFLAGS} #tạo file object từ source
$g++ -o prog main.o ${LDFLAGS} #tạo file chương trình nhị phân từ file object
Phía trên là format chung / cơ bản nhất của GCC compiler
+ CFLAGS / CXXFLAGS
C Compiler Flags và C++ preprocessor flags để pass các options vào trong compiler để thực hiện quá trình compile source
code -> object, gồm các thông tin:
- Đường dẫn các file header, bắt đầu với "-I", ví dụ: -I./include
- Các define được bắt đầu với "-D"; ví dụ: -DDEBUG, define DEBUG
- Các options đặc biết khác của compiler; ví dụ: -g (enable chức năng debug gdb của gcc compiler, -Wall (trace các warning trong quá trình compile)
+ LDFLAGS
Linker flags, dùng trong quá trình linking các thư viện, LDFLAGS chứa các thông tin:
- Đường dẫn đến thư viện, được bắt đầu bằng "-L"; ví dụ: -L./lib
- Các thư viện, bắt đầu với "-l", là viết tắt của lib; ví dụ: -lm tương ứng với libm, thư viện toán học, có sẵn trong hệ thống
+ gcc
Compiler cho C source
+ g++
Compiler cho C++ source