最简单但完整的CMake示例

编程入门 行业动态 更新时间:2024-10-08 08:26:34
本文介绍了最简单但完整的CMake示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我对CMake的工作方式完全感到困惑。每当我认为我越来越了解CMake的含义时,在我阅读的下一个示例中,它就消失了。我想知道的是,我应该如何构建我的项目,以便将来CMake所需的维护最少。例如,当我在src树中添加新文件夹时,我不想更新CMakeList.txt,该文件夹的工作方式与所有其他src文件夹完全一样。

Somehow I am totally confused by how CMake works. Every time I think that I am getting closer to understand how CMake is meant to be written, it vanishes in the next example I read. All I want to know is, how should I structure my project, so that my CMake requires the least amount of maintainance in the future. For example, I don't want to update my CMakeList.txt when I am adding a new folder in my src tree, that works exactly like all other src folders.

这就是我对项目结构的想象,但是请仅作为示例。如果建议的方法不同,请告诉我,并告诉我该怎么做。

This is how I imagine my project's structure, but please this is only an example. If the recommended way differs, please tell me, and tell me how to do it.

myProject src/ module1/ module1.h module1.cpp module2/ [...] main.cpp test/ test1.cpp resources/ file.png bin [execute cmake ..]

顺便说一句,重要的是我的程序必须知道资源在哪里。我想知道推荐的资源管理方式。经过一些研究后,我不想使用 ../ resources / file.png

By the way, it is important that my program knows where the resources are. I would like to know the recommended way of managing resources. I do not want to access my resources with "../resources/file.png"

推荐答案

访问我的资源我自己的最简单但完整的cmake示例版本。就在这里,它试图涵盖大多数基础知识,包括资源和包装。

after some research I have now my own version of the most simple but complete cmake example. Here it is, and it tries to cover most of the basics, including resources and packaging.

它做的非标准的一件事就是资源处理。默认情况下,cmake希望将它们放在/ usr / share /,/ usr / local / share /以及Windows上的等效目录中。我想要一个简单的zip / tar.gz,您可以将其提取到任何地方并运行。因此,资源是相对于可执行文件加载的。

one thing it does non-standard is resource handling. By default cmake wants to put them in /usr/share/, /usr/local/share/ and something equivalent on windows. I wanted to have a simple zip/tar.gz that you can extract anywhere and run. Therefore resources are loaded relative to the executable.

了解cmake命令的基本规则是以下语法: < function-名称>(< arg1> [< arg2> ...]),不带逗号或半彩色。每个参数都是一个字符串。 foobar(3.0)和 foobar( 3.0)是相同的。您可以使用 set(args arg1 arg2)设置列表/变量。使用此变量集, foobar($ {args})和 foobar(arg1 arg2)实际上是相同的。不存在的变量等效于一个空列表。列表在内部只是一个带有分号的字符串,用于分隔元素。因此,根据定义,仅包含一个元素的列表就是该元素,不会进行装箱。变量是全局的。内置函数提供某种形式的命名自变量,因为它们期望某些ID,例如 PUBLIC 或 DESTINATION 在其参数列表中,以对参数进行分组。但这不是语言功能,这些ID也是字符串,并由函数实现进行解析。

the basic rule to understand cmake commands is the following syntax: <function-name>(<arg1> [<arg2> ...]) without comma or semicolor. Each argument is a string. foobar(3.0) and foobar("3.0") is the same. you can set lists/variables with set(args arg1 arg2). With this variable set foobar(${args}) and foobar(arg1 arg2) are effectively the same. A non existent variable is equivalent to an empty list. A list is internally just a string with semicolons to separate the elements. Therefore a list with just one element is by definition just that element, no boxing takes place. Variables are global. Builtin functions offer some form of named arguments by the fact that they expect some ids like PUBLIC or DESTINATION in their argument list, to group the arguments. But that's not a language feature, those ids are also just strings, and parsed by the function implementation.

您可以从 github cmake_minimum_required(VERSION 3.0) project(example_project) ############################################################################### ## file globbing ############################################################## ############################################################################### # these instructions search the directory tree when cmake is # invoked and put all files that match the pattern in the variables # `sources` and `data` file(GLOB_RECURSE sources src/main/*.cpp src/main/*.h) file(GLOB_RECURSE sources_test src/test/*.cpp) file(GLOB_RECURSE data resources/*) # you can use set(sources src/main.cpp) etc if you don't want to # use globing to find files automatically ############################################################################### ## target definitions ######################################################### ############################################################################### # add the data to the target, so it becomes visible in some IDE add_executable(example ${sources} ${data}) # just for example add some compiler flags target_compile_options(example PUBLIC -std=c++1y -Wall -Wfloat-conversion) # this lets me include files relative to the root src dir with a <> pair target_include_directories(example PUBLIC src/main) # this copies all resource files in the build directory # we need this, because we want to work with paths relative to the executable file(COPY ${data} DESTINATION resources) ############################################################################### ## dependencies ############################################################### ############################################################################### # this defines the variables Boost_LIBRARIES that contain all library names # that we need to link to find_package(Boost 1.36.0 COMPONENTS filesystem system REQUIRED) target_link_libraries(example PUBLIC ${Boost_LIBRARIES} # here you can add any library dependencies ) ############################################################################### ## testing #################################################################### ############################################################################### # this is for our testing framework # we don't add REQUIRED because it's just for testing find_package(GTest) if(GTEST_FOUND) add_executable(unit_tests ${sources_test} ${sources}) # we add this define to prevent collision with the main # this might be better solved by not adding the source with the main to the # testing target target_compile_definitions(unit_tests PUBLIC UNIT_TESTS) # this allows us to use our executable as a link library # therefore we can inherit all compiler options and library dependencies set_target_properties(example PROPERTIES ENABLE_EXPORTS on) target_link_libraries(unit_tests PUBLIC ${GTEST_BOTH_LIBRARIES} example ) target_include_directories(unit_tests PUBLIC ${GTEST_INCLUDE_DIRS} # doesn't do anything on Linux ) endif() ############################################################################### ## packaging ################################################################## ############################################################################### # all install commands get the same destination. this allows us to use paths # relative to the executable. install(TARGETS example DESTINATION example_destination) # this is basically a repeat of the file copy instruction that copies the # resources in the build directory, but here we tell cmake that we want it # in the package install(DIRECTORY resources DESTINATION example_destination) # now comes everything we need, to create a package # there are a lot more variables you can set, and some # you need to set for some package types, but we want to # be minimal here set(CPACK_PACKAGE_NAME "MyExample") set(CPACK_PACKAGE_VERSION "1.0.0") # we don't want to split our program up into several things set(CPACK_MONOLITHIC_INSTALL 1) # This must be last include(CPack)

更多推荐

最简单但完整的CMake示例

本文发布于:2023-11-28 08:04:41,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1641591.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:最简单   示例   完整   CMake

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!