g++和gcc知识点回顾
关于g++和gcc
首先我们先需要安装
1
| yum install gcc gcc-c++ make cmake -y
|
然后我们测试一段简单的代码,文件名: main.cpp
1 2 3 4 5 6 7
| #include <iostream> using namespace std;
int main(){ cout << "hello" << endl; return 0; }
|
然后我们写一个简单的makefile:
1 2 3
| build: mkdir -p ./build g++ -o ./build/hello main.cpp
|
然后我们构建一下:
然后我们可以看到在文件夹build
下面生成了一个hello的可执行文件,然后我们可以运行一下它:
然后我们看到输出了hello文字。
查看依赖的系统动态链接库
然后我们看到输出了:
1 2 3 4 5 6
| linux-vdso.so.1 (0x00007ffe23449000) libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4a24e00000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4a24a00000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4a25105000) /lib64/ld-linux-x86-64.so.2 (0x00007f4a25208000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4a250e5000)
|
相当于它依赖了这些系统的库。
依赖的头文件怎么处理
- -I 头文件所在的路径
- -L 库文件所在的路径(包括动态库和静态库)
- -l 指定库的名字
然后我们代码中引用头文件,两种
1 2 3
| #include <iostream>
#include "hello.h"
|
#include <iostream>
引用系统的,一般在 /usr/include
和 /usr/local/include
目录下,我们可以通过gcc -v
查看。
而#include "hello.h"
这种则是当前项目中的头文件。
查看.a和.so文件中的接口
查看.a文件中都包含了哪些文件
查看.so文件接口
关于gcc,g++版本说明
一般C++从2011年(每三年一次,2011的新特性最多,目前使用的也最多,也最为人熟知)。
注:为了能够使用C++17的特性,需要gcc-7以上的版本
我们可以通过下面命令查看我们的编译器的版本
关于cmake说明
一个例子:
main.cpp
1 2 3 4 5 6 7
| #include <iostream> using namespace std;
int main(){ cout << "hello" << endl; return 0; }
|
然后CmakeLists.txt文件
1 2 3 4
| cmake_minimum_required(VERSION 3.13) project(helloworld) set(CMAKE_CXX_FLAGS "-std=c++17") add_executable(helloworld main.cpp)
|
然后我们新建一个build文件夹
1 2
| mkdir -p build cd build && cmake ..
|
然后默认 cmake
会生成 Unix Makefiles
,这个可以通过下面命令进行查看:
然后我们再进行build一下这个makefile的项目:
然后我们就看到生成了helloworld
这个可执行文件了。
关于CmakeLists.txt
的更多知识可以看:
https://www.jetbrains.com/help/clion/cmakelists-txt-file.html
cmake生成静态链接库和动态链接库和可执行文件的三个case
可执行文件
可执行文件:
1 2 3 4
| cmake_minimum_required(VERSION 3.13) project(helloworld) set(CMAKE_CXX_FLAGS "-std=c++17") add_executable(helloworld main.cpp)
|
这个前面已经有例子了,就不继续讲了。
静态链接库:
1 2 3 4 5
| cmake_minimum_required(VERSION 3.13) project(hello_libray) set(CMAKE_CXX_FLAGS "-std=c++17") add_library(hello_libray STATIC hello.cpp) target_include_directories(hello_libray PUBLIC ./include)
|
对应的文件:
1 2 3 4
| - include hello.h - hello.cpp - CMakeLists.txt
|
hello.h:
1 2 3 4 5 6 7 8 9 10 11
| #ifndef __HELLO__ #define __HELLO__
class Hello{ public: Hello(){}; ~Hello(){}; std::string hello(); };
#endif
|
hello.cpp:
1 2 3 4 5 6 7
| #include <iostream> #include "hello.h" using namespace std;
string Hello::hello(){ return "hello world2"; }
|
然后我们还是创建一个build文件夹,进行构建:
1 2
| mkdir -p build cd build && cmake .. && make
|
最终会生成:
如果另外一个项目要引用这个静态库怎么搞呢?
CMakeLists.tx
1 2
| add_executable(helloworld main.cpp) target_link_libraries(helloworld PRIVATE hello_libray)
|
动态链接库
我们上面静态库的时候,已经看到用到了 add_library(hello_libray STATIC hello.cpp)
add_library一共有三个参数,第一个表示:指定库的名字,第二个表示:动态还是静态,默认是静态。第三个表示: 指定生成库的源文件
1 2 3 4 5 6 7 8
| cmake_minimum_required(VERSION 3.13) project(hello_libray) set(CMAKE_CXX_FLAGS "-std=c++17") add_library(hello_libray SHARED hello.cpp) target_include_directories(hello_libray PUBLIC ./include)
add_executable(helloworld main.cpp) target_link_libraries(helloworld PRIVATE hello_libray)
|
有点像,编译出来这个有个libhello_library.so,然后我们可以用 nm -D libhello_library.so
可以看到它有暴露这个接口。
1
| 00000000000024da T _ZN5Hello5helloB5cxx11Ev
|
回忆了一下以前C语言开发的时候,做插件层,用以下方法
hello.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #ifndef __HELLO__ #define __HELLO__
class Hello{ public: Hello(){} ~Hello(){} std::string hello(); };
extern "C" { void helloworld(); }
#endif
|
hello.cpp:
1 2 3 4 5 6 7 8 9 10 11
| #include <iostream> #include "hello.h" using namespace std;
string Hello::hello(){ return "hello world2"; }
void helloworld(){ cout << "hello hello hello" << endl; }
|
这种编译出来的,我们用nm -D ./libhello_library.so
可以看到:
1
| 00000000000025ae T helloworld
|
一些资料
cmake的资料:
https://github.com/Liuyvjin/notebook/tree/master/Cmake
cmake:add_library生成静态库和动态库:
https://blog.csdn.net/zhizhengguan/article/details/111713847