C艹编译工具对比

c++的编译安装一直是阻碍C++发展的痛点,于是对于它的使用,一直在改进的路上。

它需要解决的问题无非是,编译依赖,运行依赖。编译依赖就包括了依赖的库,依赖的头文件,运行依赖主要是依赖的库。然后问题回归成版本不兼容的各种问题,平台运行不兼容的各种问题。编译的问题,编译的速度都影响它平台性的扩展。而它的编译配置文件的编写也有很多学习成本。本文就是针对编译来介绍几个常用的工具。

g++

g++是GNU开发的C++编译器,是GCC(GNU Compiler Collection)GNU编译器套件的组成部分。另外,gcc是GNU的C编译器。官方手册上的参数此时可以忽略。。。学习成本非常高。

g++ 是根据汇编的改进。 .cpp. (-E预处理)->. .i  -> (编译 -S) --> .s   -> (汇编 -c)   -> .o -->(链接)--> bin

1)静态链接库使用绝对路径,动态链接库使用-l。以boost库为例,如果我们要使用静态库则可书写如下:

 g++ main.cpp -pthread /usr/lib64/libboost_thread.a /usr/lib64/libboost_system.a

(2)使用-Wl,-Bstatic告诉链接器ld链接静态库,不存在静态库,则ld报错,只存在动态链接库也报错。使用-Wl,-Bdynamic告诉链接器优先使用动态链接库,如果只存在静态库,则链接静态库,不报错。示例如下:

g++  main.cpp -Wl,-Bstatic -lboost_system -lboost_thread -Wl,-Bdynamic

GCC VS G++

gcc和g++的主要区别

1. 对于 *.c和*.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的)

2. 对于 *.c和*.cpp文件,g++则统一当做cpp文件编译

3. 使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL

4. gcc在编译C文件时,可使用的预定义宏是比较少的

5. gcc在编译cpp文件时/g++在编译c文件和cpp文件时(这时候gcc和g++调用的都是cpp文件的编译器),会加入一些额外的宏。

6.在用gcc编译c++文件时,为了能够使用STL,需要加参数 –lstdc++ ,但这并不代表 gcc –lstdc++ 和 g++等价,它们的区别不仅仅是这个。

 

make

Makefile

f对于一个文件,用gcc/g++的编写也非常复杂,对于一个工程的make,已经不是一个脚本可以解决和覆盖的。于是有make 工具。用Makefile文件定义编译逻辑,用make工具进行编译。

GNU的make工作时的执行步骤如下:(想来其它的make也是类似)

  1. 读入所有的Makefile。
  2. 读入被include的其它Makefile。
  3. 初始化文件中的变量。
  4. 推导隐晦规则,并分析所有规则。
  5. 为所有的目标文件创建依赖关系链。
  6. 根据依赖关系,决定哪些目标要重新生成。
  7. 执行生成命令。

cmake

有了make以后工程的编译变得简单,但是Makefile还是对于平台是不兼容的,同一个工程在不同平台下,Makefile文件有不同的配置。同一份代码,不同的平台,会编不过。于是有了CMake

CMake全称为“cross platform make”,是一个开源的跨平台自动化构建系统。使用指定名为CMakeLists.txt的配置文件可以控制软件的构建、测试和打包等流程。同时,通过编写平台无关的CMakeLists.txt文件和需要简单的配置,CMake就能生成对应目标平台的构建文件,例如:类Unix系统的makefile文件、Windows的Visual Studio工程或者Mac的Xcode工程,大大简化了跨平台和交叉编译方面的工作。

cmake 是在make之前根据CMakeLists的定义生产makefile,解决不同Makefile跨平台配置的问题。让C++的工程有了跨平台的兼容性。

Bazel

Google家出的Bazel 也是跨平台的工程编译工具。更强大的优势在于,它可以支持多种开发语言的项目。

于是向tensorflow这种需要跨语言,跨平台,多文件的复杂工程,用bazel编译管理就再合适不过了。一份代码可以编译出同一版本的多语言,多平台支持的可执行文件。

命令非常简单 bazel build xxx 依赖关系定义在 BUILD文件中。

定义库

cc_library(
    name = "hello-greet",
    srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
    visibility = ["//main:__pkg__"],
)
cc_library(
    name = "sandwich",
    srcs = ["sandwich.cc"],
    hdrs = ["sandwich.h"],
    deps = [":bread"],
)

cc_library(
    name = "bread",
    srcs = ["bread.cc"],
    hdrs = ["bread.h"],
    deps = [":flour"],
)

cc_library(
    name = "flour",
    srcs = ["flour.cc"],
    hdrs = ["flour.h"],
)

定义target

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    deps = [
        ":hello-time",
        "//lib:hello-greet",
    ],
)

外部库可以用http

new_http_archive(
    name = "gtest",
    url = "https://googletest.googlecode.com/files/gtest-1.7.0.zip",
    sha256 = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d",
    build_file = "gtest.BUILD",
    strip_prefix = "gtest-1.7.0",
)
cc_library(
    name = "main",
    srcs = glob(
        ["src/*.cc"],
        exclude = ["src/gtest-all.cc"]
    ),
    hdrs = glob([
        "include/**/*.h",
        "src/*.h"
    ]),
    copts = ["-Iexternal/gtest/include"],
    linkopts = ["-pthread"],
    visibility = ["//visibility:public"],
)

bazel build main:hello-world

最后C++包的安装

linux(Centos) yum install  rpm -ivh

ubuntu : apt-get

macos  brew install

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值