C++基础学习之3 - 编译器

本文介绍了C++编译器的基础知识,强调了理解编译器的重要性,特别是GCC和G++的区别。GCC主要用于C语言编译,而G++支持C++并能链接C++库。在Linux环境下,通过命令行编译示例展示了如何使用GCC和G++,包括链接静态和动态库的选项。此外,文章还提及了Make与CMake在项目管理和自动化编译中的作用,CMake因其简化大型工程管理和提供可视化工具而被广泛采用。
摘要由CSDN通过智能技术生成

        编译器(Compiler) 是指将一种语言 翻译为另一种语言的工具,对于C++来讲,是将我们写的代码语言 转换为二进制语言(EXE或者ELF),从而能够在Windows或者Linux下运行。

        很多新同学可能对编译器并不敏感,直接用 IDE(VS、Eclipse)编译一下就可以了,没有感觉到编译器的存在,这其实就是一个问题,作者建议对于初学者尽量不要直接就用 IDE,先用 Linux命令,然后 逐渐过渡到 Vim、Emacs、Sublime等,最后才考虑用 IDE。

        我们先来看一下 GCC 和 G++

sudo apt-get install g++
sudo apt-get install gcc
        一般来讲,GCC与G++打包在一起,对于 Ubuntu 14.04 默认安装的是 4.8.4 版本,当然也可以根据自己的需要进行升级。

        GCC和G++有什么区别呢?

1. GCC是C程序编译器,将.C的后缀文件按照C语言格式编译,将.CPP文件按照C++语言格式编译;

    G++是C++编译器,在编译.C文件时调用GCC,编译.CPP文件时按照C++编译;

    错误观点:GCC只能编译C代码,G++只能编译C++代码。

2. 由于GCC无法链接C++库(但可以链接纯C),因此,对于C++链接这个工作就交给了G++;

    错误观点:编译用GCC,链接用G++。

3. GCC不会定义__cplusplus宏,而G++会;

        看一下Linux下的命令行编译的例子(sh文件build):

#!/bin/bash

SRC=`ls *.cpp`
LIBS=`ls /usr/local/lib/libopencv*.so`
g++ -I./include $SRC -o main $LIBS

        list所有的cpp文件,加载lib库(例子对应的是opencv),G++调用编译(-o 生成目标文件 main)。

> GCC Compile

gcc -o hello hello.c -I/home/include -L/home/lib -lworld
CORE_LIBS="$CORE_LIBS -L/usr/lib64/mysql -Wl,-Bstatic -lmysqlclient \ -Wl,-Bdynamic -lz -lcrypt -lnsl -lm -L/usr/lib64 -lssl -lcrypto"

    -static      # to find .a

    -shared   # to find .o (default)

    用到的两个选项: -Wl,-Bstatic 和 -Wl,-Bdynamic  告诉链接器,对接下来的-l选项使用静态链接 or 动态链接。


Make与CMake

        Make是GNU 针对复杂的编译过程开发的一个调度器,通过MakeFile文件 实现编译选项的控制、用户交互等操作。

CC = g++
SRC = `ls *.cpp`
TARGET = main
    $(CC) -I./include $SRC -o $(TARGET)
clean:
    rm main

        这是一个简单的 makefile 例子,很容易看懂,在命令行输入make,调用g++进行编译,输入clean,完成清理。

        虽然写 makefile 是程序员的必备技能,但是 有时候文件太多、逻辑太复杂,并不能够对Solution进行有效管理,基于这种考虑,CMake诞生了。

        CMake 能够生成 makefile,所以我们把它看作是上层工具,目前CMake使用较广的原因作者认为有两点:

1. CMake 对大型工程的管理更为简单,虽然也需要借助 CMakeLists.txt 文件,但维护工作量大大减少;

2. CMake 有比较好的可视化工具,这堪称利器,不解释。

        同样来看一个CMake的例子:

#
#project目录下的CMakeLists.txt
#///

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

#工程名
PROJECT(CMakeTest)

#工程文件中使用相对路径
SET(CMAKE_SUPPRESS_REGENERATION 1)
SET(CMAKE_USE_RELATIVE_PATHS ON)

#支持IF(A) ELSE()的写法
SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)

#定义工程的顶级路径
SET(PROJDIR ${CMAKE_CURRENT_SOURCE_DIR})

#定义源文件目录
SET(SRCDIR ${PROJDIR}/src)

#设置输出路径
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/build)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/build)

#设置安装路径
SET(CMAKE_INSTALL_PREFIX ${PROJDIR}/build)

#定义头文件安装目录
SET(PROJ_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/headers)

#根据操作系统不同而设置不同的路径
IF(WIN32)
 SET(GDAL_HDRS "E:/lib/gdal/include")
ELSE()
 SET(GDAL_HDRS "/home/sunsc/gdal/")
ENDIF()

#设置头文件的引用路径
INCLUDE_DIRECTORIES(
 ${GDAL_HDRS}
)

#设置引用库路径
SET(LIBS ${LIBRARY_OUTPUT_PATH})
LINK_DIRECTORIES(${LIBS})

#宏,实现visio studio的目录分组(过滤器)功能
macro(source_group_by_dir source_files)
    if(MSVC)
        set(sgbd_cur_dir ${CMAKE_CURRENT_SOURCE_DIR})
        foreach(sgbd_file ${${source_files}})
            string(REGEX REPLACE ${sgbd_cur_dir}//(.*/) //1 sgbd_fpath ${sgbd_file})
            string(REGEX REPLACE "/(.*/)/.*" //1 sgbd_group_name ${sgbd_fpath})
            string(COMPARE EQUAL ${sgbd_fpath} ${sgbd_group_name} sgbd_nogroup)
            string(REPLACE "/" "//" sgbd_group_name ${sgbd_group_name})
            if(sgbd_nogroup)
                set(sgbd_group_name "//")
            endif(sgbd_nogroup)
            source_group(${sgbd_group_name} FILES ${sgbd_file})
        endforeach(sgbd_file)
    endif(MSVC)
endmacro(source_group_by_dir)

#添加子目录
ADD_SUBDIRECTORY(src)
        除了 Make 和 CMake 之外,很多人也会用到 qmake,这里我们不再继续展开讨论,而对于 VS 对应的编译器,大家可以与 G++ 进行比较,发现其相同与不同之处,这对于编译器的理解很有好处。

        当然 如果你有兴趣自己写一个编译器的话,那将是非常有挑战的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值