创建cmake项目¶
到目前为止,创建一个CMake管理的项目是困难的。一些项目需要写近1000行代码。对于`EA`的一部分,carbin 承担了项目管理的工作,特别是对于生成插件,我们不想手动编写cmake构建系统并花费太长时间,看起来只需一秒钟就能完成。`carbin`完成了这一点。
carbin让你及时了解很少的CMake,但聪明地使用它。只需要记住,
我的源文件是什么。
我想要创建的库名称
我需要链接的依赖项
当你创建一个库时,构建完成,安装后,使用find_package(you_project REQUIRED)。好了,这就是全部!
${you_project_INCLUDE_DIR} 是你的头文件路径 you_project::xxx 是你的动态库 you_project::xxx_static 是你的静态库
创建项目¶
假设我们想创建一个名为`exodus`的项目,它由cmake提供支持。
carbin create --name exodus --test --examples --benchmark --requirements
carbin将首先下载`carbin cmake模板<https://github.com/gottingen/carbin-template>`_ cmake模板, 然后,根据你的需求更改每个文件,然后写入当前目录。
ll并查看目录:
drwxrwxr-x 2 jeff jeff 4096 4月 15 18:49 benchmark/
drwxrwxr-x 9 jeff jeff 4096 4月 15 18:49 build/
drwxrwxr-x 3 jeff jeff 4096 4月 15 18:49 carbin/
drwxrwxr-x 7 jeff jeff 4096 4月 15 18:49 carbin_cmake/
-rw-rw-r-- 1 jeff jeff 1559 4月 15 18:49 carbin_deps.txt
drwxrwxr-x 2 jeff jeff 4096 4月 15 18:49 cmake/
-rw-rw-r-- 1 jeff jeff 5373 4月 15 18:49 CMakeLists.txt
drwxrwxr-x 2 jeff jeff 4096 4月 15 18:49 conda/
drwxrwxr-x 2 jeff jeff 4096 4月 15 18:49 examples/
drwxrwxr-x 2 jeff jeff 4096 4月 15 18:49 exodus/
drwxrwxr-x 2 jeff jeff 4096 4月 15 18:49 tests/
尝试一下:
mkdir build
cd build
cmake ..
make
make test
make package
试试看~
最有可能你需要修改的是exodus/CMakeList.txt和cmake目录中的文件:
-rw-rw-r-- 1 jeff jeff 1653 4月 15 18:49 exodus_cxx_config.cmake
-rw-rw-r-- 1 jeff jeff 1341 4月 15 18:49 exodus_deps.cmake
-rw-rw-r-- 1 jeff jeff 760 4月 15 18:49 exodus_test.cmake
exodus_cxx_config.cmake 为c/c++或者asm编译标志和选项。
exodus_deps.cmake 配置依赖库链接
exodus_test.cmake 配置要运行的测试。
在项目中创建库¶
carbin创建静态和共享库,但不用担心,因为它只是将所有源代码构建为`object`,对于`C/C++`来说,它是`.o`文件,然后将它们链接到libs。
现在让我们看看exodus/CMakeLists.txt中的函数示例:
carbin_cc_library(
NAMESPACE exodus
NAME share
SOURCES
shared.cc
CXXOPTS
${CARBIN_CXX_OPTIONS}
DEPS
exodus::object
PLINKS
${CARBIN_DEPS_LINK}
exodus::object
)
这段代码创建一个名为`share`的库并导出到命名空间`exodus`。让我们看看参数。
NAMESPACE通常是项目名称,要注意它。
NAME你的库名称,它应该在你的项目中是唯一的
SOURCES c/c++文件列表可以是`shared.cc static.cc`等。
CXXOPTS c++编译选项。
COPTS c编译选项。
DEPS条件选项,例如,lib B需要A编译完成,等等…
LINKS公共链接,例如链接到openssl的动态库,调用者需要链接到它
PLINKS私有链接,仅引用你的源代码,例如,你编译一个名为hello.a的内部库,只有你的lib调用hello定义在那个lib中。
- OBJECTS由add_library(xxx OBJECT aa.cc)创建的对象文件名称或由carbin_cc_library的兄弟函数创建的对象文件
carbin_cc_object
WLINKS这是用于隐藏后端库的,它意味着将这些静态库的符号加载到你的lib中。例如,你的lib引用到zlib,当你暴露所有zlib的符号时,所有zlibstatic通过find_package找到WLINKS,因此你的lib包含zlib.
DEFINES意味着将定义添加到你的代码中,例如`NDEBUG`
INCLUDES公共包含目录
PINCLUDES私有包含目录,一个简单的规则是,如果你的头文件包含文件,使用public,否则使用private
EXCLUDE_SYSTEM选项标志,意味着不要向gcc添加-isystem标志。
PUBLIC意味着这个库将被安装和导出。例如,一个只用于测试的lib不需标记这个选项.
创建对象库¶
几乎与 carbin_cc_library 相同,几乎意味着它的参数,但这只是将源文件编译为 object ,例如,查看 obm_source 和 obm_no_source 。请记住,它不会生成完整的产品,而是半成品。 如果要导出库,需要将一个或者多个 carbin_cc_object 添加到 carbin_cc_library 的 OBJECTS 参数中。这个功能存在的意义在于,多个静态库是不能链接到一起的,但是可以链接到一个动态库中。 所有我们通过 carbin_cc_object 将多个静态库链接到一个静态库中,然后导出这个静态库,这样就可以链接到其他库中。
创建头文件库¶
如果你的库只是头文件,那么使用 carbin_cc_headers ,它只是一个头文件库,如果你没有源代码,使用这个功能,避免项目无导出对象而导致的错误。
安装¶
carbin_cc_* 已经写了安装程序,你不需要写安装程序,headers 是在主CMakeList.txt的最后安装指令,如果你想安装其他东西,写在headers安装之前或之后可能是个好主意。
对象的导出和安装¶
cmake对象的导出模版也为你导出目标,一旦你的lib安装,其他调用者可以使用 find_package(exodus REQUIRED) ,这样这个家伙就会得到exodus::shared和其他目标。 经过find_package之后, ${exodus_INCLUDE_DIR} 也会暴露给这个家伙,她可以在cmake中包含它。
测试¶
carbin提供了一种简单的测试方法,只需在 tests 目录中编写测试用例,然后在 CMakeLists.txt 中添加 carbin_cc_test ,然后运行 make test 即可。
对于 test 示例,请查看 tests 目录,如果要禁用整个项目测试,请标记 CARBIN_BUILD_TEST=OFF 定义在 carbin_option.cmake 中。 如果不想编译测试,可以这样做:
cmake .. -DCARBIN_BUILD_TEST=OFF
如果只想禁用一个测试,只需将测试标记为 DISABLED ,如下所示:
carbin_cc_test(
NAME pass_test
MODULE base
SOURCES pass_test.cc
DISABLED
)
carbin_cc_test 默认创建一个测试用例,通过 MODULE + _ + NAME 可执行二进制文件创建测试用例,并且不带参数运行。 像上面这样,如果没有标记 DISABLED ,它将创建 base_pass_test 并运行 ./base_pass_test。
有时测试用例需要命令行参数,我们通过两个步骤提供它,首先使用 carbin_cc_test 编译二进制文件 通过标记 EXT 这样:
carbin_cc_test(
NAME args_test
MODULE base
SOURCES args_test.cc
EXT
)
这将不会生成默认。然后使用 carbin_cc_test_ext 生成带参数的测试用例。像这样:
carbin_cc_test_ext(
NAME args_test
MODULE base
ALIAS skip
ARGS "SKIP"
PASS_EXP "pass;Passed"
FAIL_EXP "[^a-z]Error;ERROR;Failed"
SKIP_EXP "[^a-z]Skip" "SKIP" "Skipped"
)
`PASS_EXP` `FAIL_EXP` `SKIP_EXP` 表达式是用于测试测试输出到stdout的正则表达式,成功与否,直接运行make test更直观。
批量跳过测试¶
有时,对于测试,我们不运行所有的用例,因为我们修复了一些用例,我们只想运行这个用例。carbin_cc_test 的 MODULE 此时就派上用场了,例如,将所有测试放在两个组 do_run no_run 中,标记你想要测试的 do_run ,然后查看cmake/exodus_test.cmake,将 no_run 放到 ${PROJECT_NAME}_SKIP_TEST ,查看那个文件,你会明白一切。基准测试与测试相同。