此文章对初次或不经常接触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
将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 // 修改文件夹名 |
用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值 |
[root@admin local]# cmake --version |
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)方式二
官网http://www.boost.org/ 下载一个版本的源码
解压后,会有一个文件bootstrap.sh,执行这个脚本,会产生:
tools/build/v2/b2
tools/build/v2/bjam
这两个文件会自动复制到boost解压顶级目录,执行命令:
b2命令有很多选项,这些选项决定了以后如何使用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需要配置两个路径:
加到~/.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下面儿不是在源码目录下面,从而不会污染源码!