3.Linux编程进阶
3.1使用vs2017开发Linux
vs2017支持跨平台开发,因此使用vs2017开发linux更加方便。
由于CentOS 6.6不支持C++11,因此我们需要升级GCC到4.7或以上版本。
升级Gcc:
1.以root用户登录
2.获取安装包并解压
wget http://ftp.gnu.org/gnu/gcc/gcc-6.1.0/gcc-6.1.0.tar.bz2
tar -jxvf gcc-6.1.0.tar.bz2
3.下载编译需要的依赖项
cd gcc-6.1.0
./contrib/download_prerequisites
4.创建目录存放编译结果
mkdir gcc-build-6.1.0
cd gcc-build-6.1.0
5.生成makefile
../configure -enable-checking=release -enable-languages=c,c++ -disable-multilib
6.编译和安装
make -j4
make install
7.重启和查看版本
gcc -v
如果不升级GCC,则需要在vs2017中,项目属性:C/C++->语言->C++语言标准->C++03。
在vs2017中,没有把Linux头文件全部包含进去,因此需要手动把Linux系统下的/usr/include、/usr/local/include目录复制到VS的Linux头文件路径下,即C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\Linux\include\usr。
在vs2017中,点击调试->选项->跨平台->连接管理器->添加,将Linux服务器的主机名(连接网络后的IP)、用户名、密码填入,可以找到需要连接的Linux服务器,如下图所示,操作系统是CentOS,可以使用的平台是x86。
在vs2017中创建Linux->控制台应用程序,为了能够直接在Linux服务器中生成项目文件:右击项目->属性->平台x86->常规->远方生成根目录/远方生成项目目录->/home/lzb/linux_projects/project1,目录必须使用斜杠。由于Linux下的可执行文件无扩展名:常规->目标文件扩展名,删除掉即可。还可以将目标文件名改为hello_linux。
由于vs2017不支持CentOS6.6的执行和调试,因此可以在vs2017下编译,在Linux服务器下执行。
在vs2017界面选择x86,如下图所示。
编译无错后,远方登录Linux服务器,进入/home/lzb/linux_projects/project1/bin/x86/Debug,执行./hello_linux。
参考博客:
https://www.cnblogs.com/xylc/p/6533716.html
https://www.cnblogs.com/Harley-Quinn/p/7465517.html
3.2 Emacs
开发Linux应用程序,除了使用windows平台下的vs或Notepad++等软件,难道Linux平台下没有开发工具吗?
在前面介绍了使用vi来编辑代码,但是使用过vi的人应该知道vi使用很不方便,在这里介绍另一种Linux平台开发工具:Emacs。
Emacs是一款融合编辑、编译、调试于一体的开发环境,在较新版本的Linux发行版中,都会带有Emacs。远方登录后,可以使用命令行来启动Emacs。
启动:emacs filename,若文件存在则打开文件,若文件不存在则创建文件。在打开的Emacs窗口,分为上下两部分,上部为编辑窗口,下部为命令显示窗口。
功能键:
上下左右表示移动单个字符;
空格表示空一格字符;
Enter表示换行;
Delete表示删除单个字符;
Ctrl-x Ctrl-s表示保存文档;
Ctrl-x Ctrl-c表示退出文档;
模式:
当启动某一文件时,Emacs会自动判断文件类型,来选择相应的模式。
Esc-x modename表示进入该模式;
若modename为c-mode或c++-mode,表示进入C模式或C++模式,在这种模式下可以使用Tab来缩进或使用Ctrl-c Ctrl-c来注释选定的文本。
若modename为shell,表示进入终端模式,在这种模式下可以进行编译和执行程序。若g++ hello.cpp -o hello,./hello。 不建议使用这种模式来编译、运行代码,还不如退出Emacs来编译、运行方便。
Ctrl-x b buffername表示切换缓冲区,buffer必须为使用Emacs打开过的文件,如Ctrl-x b hello.cpp。常用来退出终端模式。
3.3编译
3.3.1 GCC
在学习Makefile之前,先了解GCC和gcc。
GCC:GNU Compiler Collection(GUN编译器集合),它可以编译C、C++、JAVA、Fortran、Object-C、Ada、Go等语言。
gcc是GCC中的GUN C Compiler(C编译器);g++是GCC中的GUN C++ Compiler(C++编译器)。
那么前面说的arm-linux-gcc和gcc又有什么区别?
使用gcc编译出来的可执行程序是在Linux系统中执行的;而arm-linux-gcc编译出来的可执行程序是在ARM-Linux下执行的,即硬件平台是ARM架构,软件平台是Linux。
由于Linux系统层的代码是由C语言编写,而系统层代码会涉及到硬件架构,因此在编译ARM架构上的程序使用arm-linux-gcc而不是arm-linux-g++。应用层只使用系统层提供的接口,与硬件架构等无关,因此使用g++而不是gcc。系统层又称底层,应用层又称上层。
3.3.2命令行编译
编译单个源文件:g++ hello.cpp -o hello。
g++表示编译器,hello.cpp表示源文件列表,-o hello表示输出文件hello。
编译多个源文件:g++ hello.cpp other.cpp -o hello。
在使用命令行编译时,只指定源文件(*.cpp),不指定头文件(*.h);由于在Linux下文件名区分大小写,因此命令行中的文件名一定不能写错。
运行程序:./hello。
./表示路径,hello表示可执行文件。
在Linux中PATH环境变量指定了可执行程序的搜索路径,在终端执行echo $PATH就会显示PATH的值。若在PATH的路径中搜索不到此可执行程序,就必须在执行程序时,加上路径。如./hello或/home/lzb/linux_projects/project1/bin/x86/Debug/hello。
Linux平台下的可执行程序时没有扩展名的。 若一个文件是可执行程序,需要满足两个条件:该文件是程序文件;该文件具有x属性。使用ls -l hello查看文件的详细信息,若无x可以用chmod添加权限。
不同平台的可执行程序,其文件格式、指令集等都不同,因此Linux平台下的可执行程序无法在其他平台执行。
3.3.3编译过程
一个C/C++文件要经过预处理、编译、汇编、链接才能生成可执行文件。在日常交流中,常使用“编译”来统称这4个步骤。
预处理:C/C++源文件中,以”#”开头的称为预处理命令,如包含命令#include、宏定义命令#define、条件编译命令#if或#ifdef。预处理的过程就是将包含的文件插入源文件中、宏定义展开、根据条件编译选择使用的代码...,最后输出到.i的文件中。
编译:将预处理后的代码翻译成汇编代码。
汇编:将汇编代码翻译成一定格式的机器代码,在Linux中为目标文件,扩展名为.o。
链接:将汇编中产生的.o目标文件和系统库的.o目标文件、库文件链接起来,生成在指定平台运行的可执行程序。
在实际交流中,使用”编译”来表示上述4个过程。
在Linux中,使用命令行编译程序,如g++ hello.cpp other.cpp -o hello,其实际分为2步。
编译不链接:
g++ ‐c hello.cpp ‐o main.o
g++ ‐c other.cpp ‐o other.o
链接:
g++ hello.o other.o ‐o hello
g++中的-c选项表示编译不链接。
可以使用nm hello.o来查看目标文件里的符号。U表示未定义(undefine),T表示定义(text),other表示函数名,v表示函数参数类型。所有的符号都必须有定义,否则报告链接所有undefined reference。