月度归档:2016年08月

静态编译跨平台程序

全静态编译程序,是c++跨平台的一个方案之一,如在ubtuntu编译,可以在centos下运行。
-static-libstdc++ -static-libgcc -static
# -static-libstdc++这个是避免使用gcc-4.8.5时产生要链接到新版本的libstdc的问题。如下
# 解决/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14′ not found
# -static-libgcc是为了解决对gcc的libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1的依赖。
# -static是为了解决其它库的动态库连接依赖,但可能会因某些库不存在静态库,可能报错。
————————————————
Debug版生成调试信息
set(CMAKE_C_FLAGS_DEBUG “${CMAKE_C_FLAGS_DEBUG} -O0 -Wall -g -ggdb3”)
SET(CMAKE_CXX_FLAGS_DEBUG “${CMAKE_CXX_FLAGS_DEBUG} -O0 -Wall -g -ggdb”)
SET(CMAKE_BUILD_TYPE Debug)
SET(CMAKE_BUILD_TYPE Debug CACHE STRING “带cache标记,是不会生成DEBUG调试信息的,也就只是Realse方式”)
Release版本生成调试信息
SET(CMAKE_C_FLAGS_RELEASE “${CMAKE_C_FLAGS_RELEASE} -O3 -Wall -g -ggdb”)
SET(CMAKE_CXX_FLAGS_RELEASE “${CMAKE_CXX_FLAGS_RELEASE} -O3 -Wall -g -ggdb”)
SET(CMAKE_BUILD_TYPE Release)
SET(CMAKE_BUILD_TYPE Relase CACHE STRING “带cache标记,是不会生成调试信息的,也就只是Realse方式”)

也可以外部指定生成方式 cmake -DCMAKE_BUILD_TYPE=Debug ./
—————————————————————
set(CMAKE_C_COMPILER “/gcc-4.8.5/bin/gcc”)
set(CMAKE_CXX_COMPILER “/gcc-4.8.5/bin/g++”)
message(“CMAKE_C_COMPILER=${CMAKE_C_COMPILER}”)
message(“CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}”)
# -static-libstdc++这个是避免使用gcc-4.8.5时产生要链接到新版本的libstdc的问题。如下
# 解决/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14′ not found
# -static-libgcc是为了解决对gcc的libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1的依赖。
# -static是为了解决其它库的动态库连接依赖,但可能会因某些库不存在静态库,可能报错。
set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -std=c++11”)
#set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -static -std=c++11”)

cpp-netlib的编译与测试

传闻cpp-netlib被提名作为boost的network库,因此我也体验一下,感觉非常优秀,相比以前使用GoLang-http或python-twisted这类框架,有优胜之处。但在编译和搭建上,会略有一些困难。在centos6.8系统里,以下是它的构建过程。
1.前期准备:
cpp-netlib版本是之匹配的boost版本,可以在cpp-netlib的CMakeList.txt里找到。
当前cpp-netlib为0.12.0版本,所对应的boost版本为v1.57.0版本。
2.下载boost-v1.57.0版本。
http://pilotfiber.dl.sourceforge.net/project/boost/boost/1.57.0/boost_1_57_0.tar.bz2
3.安装boost
tar -xf boost_1_57_0.tar.bz2
cd boost_1_57_0
./bootstrap.sh
./b2 --build-type=complete --layout=versioned
sudo ./b2 install --prefix=/boost-1.57.0

4.编辑/etc/profile文件,添加boost环境变量,并重启系统,确保环境变量生效。
export BOOST_ROOT=/boost-1.57.0
5.下载cpp-netlib,当前版本是0.12.0版本,下载地址如下:
http://downloads.cpp-netlib.org/0.12.0/cpp-netlib-0.12.0-final.tar.bz2
6.解压并修改parsers.ipp文件。
vim cpp-netlib-0.12.0-final\boost\network\protocol\http\server\impl\pasers.ipp

#include <boost/fusion/include/std_tuple.hpp>
改为
#include <boost/fusion/adapted/std_tuple.hpp>
7.编译
mkdir cpp-netlib-build
cd cpp-netlib-build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/gcc-4.8.5/bin/gcc -DCMAKE_CXX_COMPILER=/gcc-4.8.5/bin/g++ -DCMAKE_INSTALL_PREFIX=/boost-1.57.0 /home/abc/Downloads/cpp-netlib-0.12.0-final
make
sudo make install

8.上一步,仅是安装了cpp-netlib-0.12.0-final目录下network库及其相关的库文件,如下:
cppnetlib-server-parsers
cppnetlib-uri
cppnetlib-client-connections

9.上一步仍缺少asio库,它自带asio库与boost.asio有很多不一样,为了避免不必要的编译错误可能存在问题,也复制一份asio库到相应目录,如下。
cd cpp-netlib-0.12.0-final/deps/asio/asio/include
sudo cp asio asio.hpp Makefile.am /boost-1.57.0/include/ -R

注:因为只是复制头文件,在CMake中需要配置宏定义,以确保只使用头文件。
add_definitions(-DASIO_HEADER_ONLY)
10.可以编写代码测试了,为了便于测试,本人直接拷贝hello_world_async_server_with_work_queue.cpp代码,重命名为main.cpp。
11.编写CMakeList.txt文件。
cmake_minimum_required(VERSION 3.5)
project(asynhello)

set(CMAKE_C_COMPILER "/gcc-4.8.5/bin/gcc")
set(CMAKE_CXX_COMPILER "/gcc-4.8.5/bin/g++")
message("CMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
message("CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
# -static-libstdc++这个是避免使用gcc-4.8.5时产生要链接到新版本的libstdc的问题。如下
# 解决/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found
# -static-libgcc是为了解决对gcc的libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1的依赖。
# -static是为了解决其它库的动态库连接依赖,但可能会因某些库不存在静态库,可能报错。
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -std=c++11")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -static -std=c++11")
add_definitions(-DASIO_HEADER_ONLY)
set(Boost_USE_STATIC_LIBS ON) # only find static libs
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME ON)
find_package(Boost 1.57.0)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
link_directories(/boost-1.57.0/lib64)
set(SOURCE_FILES main.cpp)
add_executable(asynhello ${SOURCE_FILES})
target_link_libraries(asynhello ${Boost_LIBRARIES})
target_link_libraries(asynhello ${CMAKE_THREAD_LIBS_INIT} cppnetlib-server-parsers cppnetlib-uri cppnetlib-client-connections rt)
#使用boost_thread会导致增加libboost_system.so和libboost_thread.so两个库的引入,优先使用rt代替boost_thread。
#target_link_libraries(helloserver ${CMAKE_THREAD_LIBS_INIT} cppnetlib-server-parsers boost_thread)
endif()

注:CMake关于Boost的编写,可以下参考下文件:
https://cmake.org/cmake/help/v3.0/module/FindBoost.html
https://cmake.org/cmake/help/v3.0/manual/cmake-modules.7.html
12.编译测试
cmake ./ && make
13.测试代码
https://github.com/kxtry/cpp-netlib-example

编译boost与测试

1.下载boost_v1.57.0版本。
http://heanet.dl.sourceforge.net/project/boost/boost/1.57.0/boost_1_57_0.tar.gz
2.解压
tar -xf boost_1_57_0.tar.gz
3.进入目录,执行以下命令
cd boost_1_57_0 && ./bootstrap.sh
4.boostrap.sh会生成一个b2的执行文件。执行这个文件
./b2
默认是最小编译,也可以完全编译,他会对Boost进行完整编译,生成所有调试版、发行版的静态库和动态库,如下所示:
./b2 --build-type=complete --layout=versioned
经实践,在编译阶段–prefix参数没有意义,它只有按装阶段时,指定地址才有意义,否则仍旧默认安装在/usr/local/include目录下。
它会编译boost文件,如果报错bzlib.h头文件错误,则可以按以下命令查找
sudo yum whatprovides */bzlib.h
该命令会列表出哪些库会有这个文件,然后你安装那个库就可以了。
sudo yum install bzip2-devel
其实大部份boost的头文件可以直接引用就可以了,但部分与平台相关文件则需要编译,才行。如下这些库:
Boost.Chrono
Boost.Context
Boost.Filesystem
Boost.GraphParallel
Boost.IOStreams
Boost.Locale
Boost.MPI
Boost.ProgramOptions
Boost.Python (see the Boost.Python build documentation before building and installing it)
Boost.Regex
Boost.Serialization
Boost.Signals
Boost.System
Boost.Thread
Boost.Timer
Boost.Wave
5.安装boost
./b2 install
头文件会安装到/usr/local/include目录下,库文件会安装在/usr/local/lib下。
./b2 install --prefix=/boost-1.57.0
指定安装目录。
6.在CMake环境中测试。
CMakeLists.txt中编辑如下:
cmake_minimum_required(VERSION 3.5)
project(boostTest)

include_directories("/gcc-4.8.5/include/c++/4.8.5")
include_directories("/usr/local/include/")
link_directories("/usr/local/lib")
link_directories("/gcc-4.8.5/lib64")
set(CMAKE_C_COMPILER "/gcc-4.8.5/bin/gcc")
set(CMAKE_CXX_COMPILER "/gcc-4.8.5/bin/g++")

#等价于cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=/gcc-4.8.5/bin/gcc -DCMAKE_CXX_COMPILER=/gcc-4.8.5/bin/g++ /home/abc/Downloads/cpp-netlib-0.12.0-final
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SOURCE_FILES main.cpp)
add_executable(boostTest ${SOURCE_FILES})

在main.cpp文件如下
#include
#include

int main() {
std::cout << "Hello, World!" << std::endl; std::cout << "Using Boost " << BOOST_VERSION / 100000 << "." // major version << BOOST_VERSION / 100 % 1000 << "." // minor version << BOOST_VERSION % 100 // patch level << std::endl; return 0; }

7.编译执行试试。

修改YII的请求参数

在YII2中,由于封装了大量的插件,很多插件是依赖Yii::$app->request->queryParams这样的参数,如Sort排序,Linkpager分页、Gridview表格等,因此有时因需要是有必要修改该参数。由于queryParams是只读属性,不能直接修改。但它提供了显式的setQueryParams的函数,让你修改。如下所示
$searchModel = new BookSearch();
$params = Yii::$app->request->queryParams;
if(isset($params['sort'])){
$cookies = Yii::$app->response->cookies;
$cookies->add(new \yii\web\Cookie([
'name' => $this->id.'_index_sort',
'value' => $params['sort'],
'expire'=>time()+3600
]));
}else{
$cookies = Yii::$app->request->cookies;
$sort = $cookies->get($this->id.'_index_sort', '');
$params['sort'] = $sort->value;
Yii::$app->request->setQueryParams($params);
}
$dataProvider = $searchModel->search($params);

id

gcc4.8.5与gdb7.11编译

在centos6.8系统上
gcc编译如下:
1.安装C++静态编译库,(据说是可以编译出静态库文件)。

yum install glibc-static libstdc++-static -y

2.在源码目录下,执行gcc的预安装检查,缺少相应文件,则会下载(gmp、mpc、mpfr这三个依赖库)。
由于gmp,mpc,mpfr这三个库是联网国外下载,国内可能被墙的原因,可按如下方式下载。

vim ./contrib/download_prerequisites
检查gmp,mpc,mpfr的相应版本号,并把相应的下载地址指你的个人地址。如本人的
http://kxtry.com/upload/mpc-0.8.1.tar.gz
http://kxtry.com/upload/mpfr-2.4.2.tar.bz2
http://kxtry.com/upload/gmp-4.3.2.tar.bz2

cd gcc-4.8.5
./contrib/download_prerequisites

3.创建gcc-4.8.5的兄弟目录。
mkdir gcc-build-4.8.5
4.配置

cd gcc-build-4.8.5
../gcc-4.8.5/configure --prefix=/gcc-4.8.5 --enable-checking=release --enable-languages=c,c++ --disable-multilib
--enable-checking:禁止检查,可以加快编译速度
--disable-multilib:禁用多平台支持。
--enable-languages:仅限c及c++的编译

5.编译
make

GDB的安装较简便:

cd gdb-7.11.1
./configure --prefix=/gdb-7.11.1
make

6.在CMake中使用如下:
cmake_minimum_required(VERSION 3.5)

project(untitled)

set(CMAKE_C_COMPILER “/gcc-4.8.5/bin/gcc”)
set(CMAKE_CXX_COMPILER “/gcc-4.8.5/bin/g++”)

set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -std=c++11”)

set(SOURCE_FILES main.cpp)
add_executable(untitled ${SOURCE_FILES})
7.检验c++11是否编译及调试正常。