参考资料:
Makefile和CMakeLists的区别
Cmake编写CmakeList.txt 语法备忘
GCC(GNU Compiler Collection)是由 GNU 开发的编程语言编译器,可以在 Windows 和 Linux 等各种系统上编译代码。Windows 上的 Visual Studio 是个不错的编程工具,但是它有不少烦人的限制(比如不能内联汇编),而且它的 .sln
和 .vcxproj
不能在 Linux 上使用。
我们结合两者优点,先使用 VS 的 CMake 项目
来编程,然后用 gcc
编译得到在各个平台通用的代码。但是 gcc
编译时,需要对各个文件进行排序,否则容易链接失败。
可以使用 make
工具,根据 Makefile
文件指定编译配置。不过,编写 MakeFile
也是一件体力活。
进一步,我们使用 CMake
工具,根据 CMakeLists.txt
文件来生成 MakeFile
文件。
注意,我们的编译是在 Linux 上进行的,在 Windows 上可以使用 WSL 直接对本地文件进行处理。
这样,就可以比较方便地用 gcc
编译大型工程了 ヾ(๑╹◡╹)ノ"
这里只介绍一些基本的语法,足够日常的使用了。
我不再详细地一一介绍,就写个简单的注释,备忘:
cmake_minimum_required(VERSION 3.10) #指定最小版本project(MyProject C ASM) #指定工程名称以及类型set(CMAKE_C_STANDARD 11) #指定C11
set(CMAKE_CXX_STANDARD 11) #指定C++11
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_Cxx_STANDARD_REQUIRED ON)enable_language(ASM) #启用汇编
SET(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS asm) #设置后缀set(CMAKE_BUILD_TYPE Release) #设置Debug还是Releaseinclude_directories(SYSTEM) #设置include目录
link_directories(SYSTEM) #设置static/dll目录#也可以设置为工作目录下的一些文件夹
include_directories(${PROJECT_SOURCE_DIR}/openssl)
link_directories(${PROJECT_SOURCE_DIR}/openssl/lib ${PROJECT_SOURCE_DIR}/lib/)SET( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) #设置exe文件目录,放置后续的add_executable结果
SET( LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib/) #设置static/dll库目录,放置后续的add_library结果#nasm或yasm不支持-mavx2,-maes等指令,所以须前置
#但编译出的TIMER.a似乎链接不上?一直找不到func。其他的由C代码编译出的库可以正常链接
add_library(TIMER cputimer.asm) #编译asm文件为静态库
add_library(TIMER SHARED cputimer.asm) #编译asm文件为动态库#为后续的所有gcc命令设置编译参数
#这里的-lm,-lcrypto似乎没用?
add_compile_options(-w -O3 -lm -lssl -lcrypto -maes -mavx2-Wall -Wextra -Wpedantic -Wmissing-prototypes -Wredundant-decls -Wshadow -Wpointer-arith
)#将源文件分组(头文件不需要,已经被include写入源文件)
set(A_SRCS a1.c a2.c a3.c)
set(B_SRCS b1.c b2.c b3.c b4.c)
set(C_SRCS c1.c c2.c)
set(D_SRCS d1.c)#将测试文件分组
set(TEST_B_SRCS test_b.c)
set(TEST_C_SRCS test_c.c)
set(TEST_D_SRCS test_d.c)#递归执行src子目录下的CMakeLists.txt(如果有的话)
add_subdirectory(src)add_library(B ${A_SRCS} ${B_SRCS}) #编译出静态库
add_library(C SHARED ${A_SRCS} ${C_SRCS}) #编译出动态库
target_link_libraries(B PUBLIC m) #添加math库
target_link_libraries(C INTERFACE crypto) #添加openssl库#对于同样的代码,设置不同的宏
add_library(D128 ${D_SRCS})
add_library(D256 ${D_SRCS})
target_compile_definitions(D128 PUBLIC SAFETY=128) #新建一个宏,取值128
target_compile_definitions(D256 PUBLIC SAFETY=256) #新建一个宏,取值256link_libraries(m) #后续的所有gcc指令都链接math库#编译各个main文件得到exe文件,并链接对应的库
add_executable(test_b ${B_SRCS})
add_executable(test_c ${C_SRCS})
add_executable(test_d128 ${D_SRCS})
add_executable(test_d256 ${D_SRCS})
target_link_libraries(test_b B)
target_link_libraries(test_c C)
target_link_libraries(test_d128 D128)
target_link_libraries(test_d256 D256)
为了让上述的 target_compile_definitions
起作用,需要这么写 .h
文件:
#ifndef SAFETY#define SAFETY 128 // 设置安全强度
#endif
编译步骤:
WSL
进入工作目录cmake ./
生成 MakeFile
文件make
编译工程代码/bin
内的 .exe
文件是否正确/lib
内在 Windows 下使用 gcc, make, cmake
也可以,但是本人的工程代码(简单逻辑的代码没问题)出现了
internal error: aborting at ../../ld/ldlang.c:527 in compare_section
的错误,查了好多资料,还是搞不懂哪儿出错了(弱小又无助)
另外,Windows 下的 openssl
一直找不到 PATH
里写明了的 include
以及 lib
的位置,还要手动复制到工作目录下,烦死了 (╬ ̄皿 ̄)