Monday, June 29, 2015

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:

 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à PATHLD_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.

Leave a Reply

Subscribe to Posts | Subscribe to Comments

- Copyright © Lập trình hệ thống nhúng Linux . Powered by Luong Duy Ninh -