linux系统初次使用cmake编译boost项目

此文章对初次或不经常接触linux的人比较重要,linux开发经验丰富的请飘过!一个人良好的习惯就是不断的学习、不断的做笔记,然后吸收为己用. 与此同时为他人做点贡献,学到东西,然后贡献东西,这就是进步的良性互动!

我一直从事windows开发多年,一直很忙也很少接触linux系统,但是关于跨平台的项目做的很少,而实际上夸平台的项目大多是与服务器相关的,随着对boost的熟练使用和有关服务器经验的积累,心理一直有将windows下的中间件或服务器改编成跨平台的项目的想法,使项目不依赖具体的系统(当然我们开发的时候一般做的都是使用预编译处理,也就是通过预编译使用两套或多套与系统的API,这个工作量可想而知!),最近想通了,自己能力是有限的,不能将所有的项目、组建、功能都自己一个人扛下来,有了这个想法之后,后续所有的工作只搭建框架,其他的东西都交给下面的人完成,最后做一个检验性的工作即可,这时候,时间终于空闲下来了,有机会开始学习了,如下就是我在linux下使用cmake过程中遇到的关于linux环境问题、安装部署问题以及编译问题;


1、linux系统的安装

对于很多接触过linux系统的人来说,linux系统的安装只不过是小菜一碟而已,但是对于一个一直从事windows开发的人来说,其中的一些细节却很难把握,这里我就不细细道来,网络上关于系统安装有一大把的文章,此处我要说的几点:

(1)安装并不需要安装实体系统,简单的虚拟机就可以了,为什么呢?接触过linux的人知道,linux下所有的东西都是通过shell控制的,即使有带图形界面的系统也很难使用,其次开发使用vim不方便,难度太大,编辑起来很繁琐,用惯了windows的朋友都很清楚这点,如果我们结合windows与linux,对于开发人来说是一个莫大的进步,其他大家也都是这么干的,windows下安装虚拟机然后安装linux系统,用linux系统做编译,用windows下的编辑器做代码编辑,所以选择虚拟机是开发绝佳选择;

(2)系统安装使用的虚拟机有开源的和收费的,如workstations是收费的,vmplayer是免费的,其实免费的已经能满足我们所有要求了,并且在上市公司盗版软件查的严,所以建议使用vmplayer即可;

(3)安装过程中,可以下载linux各种版本的包,有DVD ISO的、完全版的、minimal阉割版的,版本有centos、 ubuntu、 fedora、debian等,这里我选择的是centos,在官网下载最新的 https://www.centos.org/download/


这里,我没不用完全版的,下载迷你版的即可,需要安装的东西自己安装。

(4)另外安装的时候,虚拟机上选择系统iso文件的时候,让你选择系统类型,你要根据你下载的包选择相应系统类型,不然选择错了虚拟机一直卡死无法安装,这里都是x86_64,当初以为是32bit和64bit都支持的,选择错了,出了这么一招... 其实是64bit系统,所有你选择centos64而不是centos,选择好后一步一步安装即可;


2、系统挂载

对于开发员来说,借用windows编辑、linux编译是必备模式,但是涉及到系统之间的文件共享,我们如果做呢?一般情况下我们可以用vmplayer里面的共享文件夹功能,添加可以共享的文件夹即可,这是后启动机器后,默认挂载到/mnt/hgfs下面去了,我问过做linux同事,一般他们不用虚拟机的这个共享功能,而比较通用的做法和windows文件共享一样,就是通过文件或文件夹属性的共享功能共享文件或文件夹,所有我也是这么用的,注意为了共享的东西只能你看到,你必须指定权限到某人而不是所有人,还有指定的时候,必须设置可读写!


如果没用户,你创建一个用户(当然用户可能是域用户!)

linux系统安装后,如果你没创建普通用户,那么用命令创建一个,一般开发不会直接用root用户直接去操作,太危险了,所有咱们按常规来,如果需要创建用户,那么使用如下命令:

useradd -m -s /bin/bash demon 

其中 -m表示给用户创建home目录,-s 表示启用该用户 /bin/bash表示给用户创建shell环境,demon为用户名,随后输入密码即可,完成后再/home下便有了demon的目录了,在shell中使用demon即可登录;


(1)常用命令

关于linux中的文章也很多,我这里可以提供给大家“一本”很好的书,其实就是经验总结,对于初学者有很大帮助,里面讲的很详细对开发来说很实用,这里我共享一下,给我点功劳分就好了,感谢,好不好大家也评论一下,为其他人指点出路!


(2)临时挂载

这里我windows共享的文件夹为windows-linux,为了在linux下好识别,我在linux下个人home也建同名的文件夹,方便识别查找(/home/lixiang/windows-linux),

首先进入个人目录(普通用户登录) ,使用“cd ~"即可进入,这里为/home/lixiang ,使用mkdir创建windows-linux “mkdir windows-linu”,如果没权限,切换到root后创建

(输入su回车输入root密码切换到root用户,然后mkdir windows-linux)即可;

   之后,我们要做的就是将windows下windows-linux挂在到/home/lixiang/windows-linux目录,使用命令如下(必须切换到root用户后):

      mount -o username=用户名无引号,domain=域名无引号,password=密码无引号  //192.168.0.102/windows-linux   ./windows-linux

其中domain为域名,不管是本机还是域用户头填写一下,如我这里域名写的是PC-lixiang也就是计算机属性里看到的计算机名;这样windows-linux就被挂在上了,使用cd进入该目录和ll命令查看即可列出目录内容;


(2)自动挂载

  每次进入系统挂在是十分麻烦的事情,于是我就搜索发现可以使用root用户修改/etc/fstab文件,在最后添加如下挂载内容即可:

//192.168.0.102/windows-linux /home/lixiang/windows-linux cifs auto,username=lixiangxiang,domain=PC-lixiangxiang,password=我的密码 0 0

其中192.168.0.102为windows系统ip(对了说道这里linux系统网络连接可以在虚拟机网络配置哪里改成net地址转换模式,这样使用主机网络联网即可);cifs为普通internet文件系统协议,smb协议基本取消,username和密码等基本说明,密码后面有一个空格,和两个0(之间有空格);重启后,使用“df -h"就能看到系统磁盘信息,包括挂在的磁盘信息



3、gcc安装

这里gcc安装必须要安装支持c++的才行,在windows开发你不会没用c++吧?这个不太可能,所有我们用c++编译器,安装命令

       yum install gcc-c++  (安装时候必须有root权限)

3、cmake安装

软件:cmake-2.8.10.2.tar.gz
下载地址:http://www.cmake.org/cmake/resources/software.html

(1)安装cmake

将cmake-2.8.10.2.tar.gz文件上传到/usr/local中执行以下操作:

[root@admin local]# cd /usr/local
[root@admin local]# tar -zxv -f cmake-2.8.10.2.tar.gz       // 解压压缩包 
[root@admin local]# rm -rf cmake-2.8.10.2.tar.gz   // 删除压缩包 
[root@admin local]# cd cmake-2.8.10.2
[root@localhost cmake-2.8.10.2]# ./configure
[root@localhost cmake-2.8.10.2]# make
[root@localhost cmake-2.8.10.2]# make install
[root@admin local]# mv cmake-2.8.10.2 cmake  // 修改文件夹名

(2)添加环境变量

用vi在文件/etc/profile文件中增加变量,使其永久有效:

[root@admin local]# vi /etc/profile   // 修改环境变量

在文件末尾追加以下两行代码:

PATH=/usr/local/cmake/bin:$PATH
export PATH

然后执行以下操作:

[root@admin local]# source /etc/profile   //使修改生效 
[root@admin local]#    echo $PATH   //查看PATH值

(3)检验cmake安装

[root@admin local]# cmake --version
cmake version 2.8.10.2


4、boost库安装

(1)方式一

如果怕源码编译麻烦,就可以使用yum自动安装,如:

sudo yum install boost-devel.x86_64 boost-test.x86_64 boost.x86_64

编译后默认:

头文件目录: /usr/include/boost/

库文件目录:(on Fedora)
/lib64/libboost_thread.so
/lib64/libboost_atomic.so
/lib64/libboost_chrono.so
/lib64/libboost_date_time.so
/lib64/libboost_context.so
/lib64/libboost_log.so
/lib64/libboost_locale.so
/lib64/libboost_iostreams.so
/lib64/libboost_graph.so
/lib64/libboost_filesystem.so
/lib64/libboost_math_c99.so
/lib64/libboost_math_c99l.so
/lib64/libboost_math_c99f.so
/lib64/libboost_log_setup.so
/lib64/libboost_math_tr1.so
/lib64/libboost_math_tr1l.so
/lib64/libboost_math_tr1f.so
/lib64/libboost_random.so
/lib64/libboost_python.so
/lib64/libboost_program_options.so
/lib64/libboost_prg_exec_monitor.so
/lib64/libboost_system.so
/lib64/libboost_signals.so
/lib64/libboost_serialization.so
/lib64/libboost_regex.so
/lib64/libboost_timer.so
/lib64/libboost_wserialization.so
/lib64/libboost_wave.so
/lib64/libboost_unit_test_framework.so

(2)方式二

 如果对boost的使用想自己配置的更加灵活些,可以采用源码安装方式:

官网http://www.boost.org/ 下载一个版本的源码

解压后,会有一个文件bootstrap.sh,执行这个脚本,会产生:

tools/build/v2/b2
tools/build/v2/bjam

这两个文件会自动复制到boost解压顶级目录,执行命令:

b2 --toolset=gcc link=static runtime-link=static threading=multi --without-python stage --stagedir=./ debug release --includedir=/usr/include/ --libdir=/usr/lib/boost


b2命令有很多选项,这些选项决定了以后如何使用boost:

  • toolset,指定编译器
  • link,编译成静态库static,或者动态库share,但一般是使用static
  • threading,使用多线程则是multi,否则为single
  • runtime-link,动态链接shared或静态链接static
  • with/without,选择编译或不编译指定的库
  • stage/install,推荐使用stage,只生成lib文件,而boost源码目录作为头文件目录
  • stagedir/prefix, stage时使用stagedir,install时用prefix,用于存放编译生成文件的路径
  • debug/release,一般程序的debug release版本对应boost库的debug release版本,因此两个都编译
  • includedir=/usr/include/,指定头文件的安装目录
  • libdir=/usr/lib/boost,指定库文件安装路径

完全安装

也可以进行完全编译,需要等待很长时间:

$b2 --build-type=complete

静态库文件(on Mac):

/opt/local/lib/libboost_atomic-mt.a
/opt/local/lib/libboost_atomic-mt.dylib
/opt/local/lib/libboost_chrono-mt.a
/opt/local/lib/libboost_chrono-mt.dylib
/opt/local/lib/libboost_context-mt.a
/opt/local/lib/libboost_context-mt.dylib
/opt/local/lib/libboost_coroutine-mt.a
/opt/local/lib/libboost_coroutine-mt.dylib
/opt/local/lib/libboost_date_time-mt.a
/opt/local/lib/libboost_date_time-mt.dylib
/opt/local/lib/libboost_exception-mt.a
/opt/local/lib/libboost_filesystem-mt.a
/opt/local/lib/libboost_filesystem-mt.dylib
/opt/local/lib/libboost_graph-mt.a
/opt/local/lib/libboost_graph-mt.dylib
/opt/local/lib/libboost_iostreams-mt.a
/opt/local/lib/libboost_iostreams-mt.dylib
/opt/local/lib/libboost_locale-mt.a
/opt/local/lib/libboost_locale-mt.dylib
/opt/local/lib/libboost_log-mt.a
/opt/local/lib/libboost_log-mt.dylib
/opt/local/lib/libboost_log_setup-mt.a
/opt/local/lib/libboost_log_setup-mt.dylib
/opt/local/lib/libboost_math_c99-mt.a
/opt/local/lib/libboost_math_c99-mt.dylib
/opt/local/lib/libboost_math_c99f-mt.a
/opt/local/lib/libboost_math_c99f-mt.dylib
/opt/local/lib/libboost_math_c99l-mt.a
/opt/local/lib/libboost_math_c99l-mt.dylib
/opt/local/lib/libboost_math_tr1-mt.a
/opt/local/lib/libboost_math_tr1-mt.dylib
/opt/local/lib/libboost_math_tr1f-mt.a
/opt/local/lib/libboost_math_tr1f-mt.dylib
/opt/local/lib/libboost_math_tr1l-mt.a
/opt/local/lib/libboost_math_tr1l-mt.dylib
/opt/local/lib/libboost_prg_exec_monitor-mt.a
/opt/local/lib/libboost_prg_exec_monitor-mt.dylib
/opt/local/lib/libboost_program_options-mt.a
/opt/local/lib/libboost_program_options-mt.dylib
/opt/local/lib/libboost_python-mt.a
/opt/local/lib/libboost_python-mt.dylib
/opt/local/lib/libboost_random-mt.a
/opt/local/lib/libboost_random-mt.dylib
/opt/local/lib/libboost_regex-mt.a
/opt/local/lib/libboost_regex-mt.dylib
/opt/local/lib/libboost_serialization-mt.a
/opt/local/lib/libboost_serialization-mt.dylib
/opt/local/lib/libboost_signals-mt.a
/opt/local/lib/libboost_signals-mt.dylib
/opt/local/lib/libboost_system-mt.a
/opt/local/lib/libboost_system-mt.dylib
/opt/local/lib/libboost_test_exec_monitor-mt.a
/opt/local/lib/libboost_thread-mt.a
/opt/local/lib/libboost_thread-mt.dylib
/opt/local/lib/libboost_timer-mt.a
/opt/local/lib/libboost_timer-mt.dylib
/opt/local/lib/libboost_unit_test_framework-mt.a
/opt/local/lib/libboost_unit_test_framework-mt.dylib
/opt/local/lib/libboost_wave-mt.a
/opt/local/lib/libboost_wave-mt.dylib
/opt/local/lib/libboost_wserialization-mt.a
/opt/local/lib/libboost_wserialization-mt.dylib

如果时间足够,就进行完全编译,想怎么用都可以;事实上编译完成后除了boost和bin目录之外其他目录和文件已经可以删除了。

使用boost编程

  • Linux中的动态链接库是.so文件
  • Windows中的动态链接库是.dll文件
  • Mac中的动态链接库是.dylib文件

Linux动态链接编译 (.so)

使用boost需要配置两个路径:

  • include目录
  • library目录

加到~/.bashrc

BOOST_INCLUDE=/usr/include/boost
export BOOST_INCLUDE

BOOST_LIB=/lib64/
export BOOST_LIB

4、使用cmake和boost库

cmake:3.3 

boost:1.59.0 

boost位置:/opt/boost

代码布局:

?
1
2
3
4
5
6
7
8
➜  filesystem  tree
.
├── build
├── CMakeLists.txt
└── tut1.cpp
 
1 directory, 2 files
➜  filesystem

build即为我执行cmake 和 make的目录

tut1.cpp[来自boost自带的示例代码]

//  filesystem tut1.cpp  ---------------------------------------------------------------//
 
//  Copyright Beman Dawes 2009
 
//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt
 
//  Library home page: http://www.boost.org/libs/filesystem
 
#include 
#include 
 
using  namespace  boost::filesystem;
 
int  main( int  argc,  char * argv[])
{
   if  (argc < 2)
   {
     std::cout <<  "Usage: tut1 path\n" ;
     return  1;
   }
   std::cout << argv[1] <<  " "  << file_size(argv[1]) <<  '\n' ;
   return  0;
}



CMakeLists.txt:

cmake_minimum_required(VERSION 3.3)
 
project(cmaketest CXX)
#project(cmaketest)
 
 
set (BOOST_ROOT  "/opt/boost" )
 
#set(Boost_USE_STATIC_LIBS ON)
#set(Boost_USE_MULTITHREADED ON)
#set(Boost_USE_STATIC_RUNTIME OFF)
 
 
# filesystem依赖system
#
find_package(Boost REQUIRED COMPONENTS
#  regex
filesystem
system
)
 
if (NOT Boost_FOUND)
   message( "未发现Boost" )
endif()
 
 
aux_source_directory(. srcs)
 
include_directories(${Boost_INCLUDE_DIRS}
#  /opt/boost/lib
   )
 
 
add_executable(hello ${srcs})
 
target_link_libraries(hello ${Boost_LIBRARIES})


注意:

1、设置BOOST_ROOT

2、使用find_package时,不能简单的写find_package(Boost),应当把你需要使用的boost的库的名称也写下来,比如boost_filesystem,就写为filesystem,也就是去掉boost_前缀

3、注意库之间的依赖关系,我之前写的时候在find_package中只写了filesytem,cmake执行没错,但是make时错误提示如下:

➜  build   make
Scanning dependencies of target hello
[ 50%] Building CXX object CMakeFiles /hello . dir /tut1 .cpp.o
[100%] Linking CXX executable hello
/usr/bin/ld .bfd.real: CMakeFiles /hello . dir /tut1 .cpp.o: undefined reference to symbol  '_ZN5boost6system15system_categoryEv'
/opt/boost/lib/libboost_system .so.1.59.0: error adding symbols: DSO missing from  command  line
collect2: error: ld returned 1  exit  status
make [2]: *** [hello] 错误 1
make [1]: *** [CMakeFiles /hello . dir /all ] 错误 2
make : *** [all] 错误 2
➜  build


注意: cmake_source_directory 和cmake_bin_directory一般情况下一样,如果编译的时候,source为源码目录,bin为编译目录,为了不污染源码可以在源码下建立build目录,在linux下进入该目录后 使用cmake .. (指定CMakeLists.txt在build目录的父目录里),这编译的中间东西都在build下面儿不是在源码目录下面,从而不会污染源码!


你可能感兴趣的:(linux)