cmake 多文件夹(cmake 多个可执行文件)

cmake 多文件夹(cmake 多个可执行文件)多个源文件 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 上篇我们学习了单个源文件的 cmake 的编译 不过一个源文件的例子似乎没什么意思 我们再加入一个 hello h 头文件和 hello c 源文件 在 hello c 文件中 定义了一个函数 hello 然后在 main c 源文件中将会调用该函数 nbsp nbsp nbsp nbsp nbsp nbsp nbsp




多个源文件

        上篇我们学习了单个源文件的cmake 的编译,不过一个源文件的例子似乎没什么意思,我们再加入一个hello.h 头文件和 hello.c 源文件。在 hello.c 文件中 定义了一个函数 hello,然后在 main.c 源文件中将会调用该函数:

        ⚫ hello.h 文件内容

        ⚫ hello.c 文件内容

        ⚫ main.c 文件内容

        ⚫ 然后准备好 CMakeLists.txt 文件

        工程目录结构如下所示:

        同样,进入到build目录下,执行cmake、再执行make编译工程,最终就会得到可执行文件 hello。

        在本例子中,CMakeLists.txt 文件中使用到了 set 命令,set 命令用于设置变量,如果变量不存在则创建该变量并设置它;在本例中,我们定义了一个 SRC_LIST 变量,SRC_LIST 变量是一个源文件列表,记录生成可执行文件 hello 所需的源文件 main.c 和 hello.c,而在 add_executable 命令引用了该变量;当然我们也可以不去定义 SRC_LIST 变量,直接将源文件列表写在 add_executable 命令中,如下:

生成库文件

       在本例中,除了生成可执行文件 hello 之外,我们还需要将 hello.c 编译为静态库文件或者动态库文件, 在上个例子的基础上对 CMakeLists.txt 文件进行修改,如下所示:

        进入到 build 目录下,执行 cmake、再执行 make 编译工程,编译完成之后,在 build 目录下就会生成可执行文件 hello 和库文件,如下所示:

cmake target_link_libraries 多个so文件 cmake多文件编译_linux

         目录结构如下所示:

CMakeLists.txt 文件解释

        本例中我们使用到了 add_library 命令和 target_link_libraries 命令。 add_library 命令用于生成库文件,在本例中我们传入了两个参数,第一个参数表示库文件的名字,需要注意的是,这个名字是不包含前缀和后缀的名字;在 Linux 系统中,库文件的前缀是 lib,动态库文件的后缀是.so,而静态库文件的后缀是.a;所以,意味着最终生成的库文件对应的名字会自动添加上前缀和后缀。

        第二个参数表示库文件对应的源文件。

        本例中,add_library 命令生成了一个静态库文件 liblibhello.a,如果要生成动态库文件,可以这样做:

target_link_libraries 命令为目标指定依赖库,在本例中,hello.c 被编译为库文件,并将其链接进 hello 程序。

修改生成的库文件名字

本例中有一点非常不爽,生成的库为 liblibhello.a,名字非常不好看;如果想生成 libhello.a 该怎么办? 直接修改 add_library 命令的参数,像下面这样可以吗?

        答案是不行的,因为 hello 这个目标已经存在了(add_executable(hello main.c)),目标名对于整个工程来说是唯一的,不可出现相同名字的目标,所以这种方法肯定是不行的,实际上我们只需要在 CMakeLists.txt 文件中添加下面这条命令即可:

        set_target_properties 用于设置目标的属性,这里通过 set_target_properties 命令对 libhello 目标的 OUTPUT_NAME 属性进行了设置,将其设置为 hello。

        我们进行实验,此时 CMakeLists.txt 文件中的内容如下所示:

        除了添加 set_target_properties 命令之外,我们还加入了 cmake_minimum_required 命令,该命令用于设置当前工程的 cmake 最低版本号要求,当然这个并不是强制性的,但是最好还是加上。进入到 build 目录下, 使用 cmake+make 编译整个工程,编译完成之后会发现,生成的库文件为 libhello.a,而不是 liblibhello.a。

将源文件组织到不同的目录

        上面的示例中,我们已经加入了多个源文件,但是这些源文件都是放在同一个目录下,这样还是不太正规,我们应该将这些源文件按照类型、功能、模块给它们放置到不同的目录下,于是笔者将工程源码进行了整理,当前目录结构如下所示:

        在工程目录下,我们创建了 src 和 libhello 目录,并将 hello.c 和 hello.h 文件移动到 libhello 目录下,将 main.c 文件移动到 src 目录下,并且在顶层目录、libhello 目录以及 src 目录下都有一个 CMakeLists.txt 文件。 CMakeLists.txt 文件的数量从 1 个一下变成了 3 个,顿时感觉到有点触不及防!还好每一个都不复杂!我们 来看看每一个 CMakeLists.txt 文件的内容。

        ⚫ 顶层 CMakeLists.txt

        ⚫ src 目录下的 CMakeLists.txt

        ⚫ libhello 目录下的 CMakeLists.txt

        顶层 CMakeLists.txt 中使用了 add_subdirectory 命令,该命令告诉 cmake 去子目录中寻找新的 CMakeLists.txt 文件并解析它;而在 src的 CMakeList.txt 文件中,新增加了 include_directories 命令用来指明头文件所在的路径,并且使用到了 PROJECT_SOURCE_DIR 变量,该变量指向了一个路径,从命名上可知, 该变量表示工程源码的目录。

        和前面一样,进入到 build 目录下进行构建、编译,最终会得到可执行文件 hello(build/src/hello)和库文件 libhello.a(build/libhello/libhello.a):

将生成的可执行文件和库文件放置到单独的目录下

        前面还有一点不爽,在默认情况下,make 编译生成的可执行文件和库文件会与 cmake 命令产生的中间文件(CMakeCache.txt、CmakeFiles、cmake_install.cmake 以及 Makefile 等)混在一起,也就是它们在同一 个目录下;如果我想让可执行文件单独放置在 bin 目录下,而库文件单独放置在 lib 目录下,就像下面这样:

        将库文件存放在 build 目录下的 lib 目录中,而将可执行文件存放在 build 目录下的 bin 目录中,这个时候又该怎么做呢?这个时候我们可以通过两个变量来实现,将 src 目录下的 CMakeList.txt 文件进行修改, 如下所示:

        然后再对 libhello 目录下的 CMakeList.txt 文件进行修改,如下所示:

        修改完成之后,再次按照步骤对工程进行构建、编译,此时便会按照我们的要求将生成的可执行文件 hello 放置在 build/bin 目录下、库文件 libhello.a 放置在 build/lib 目录下。最终的目录结构就如下所示:

        其实实现这个需求非常简单,通过对 LIBRARY_OUTPUT_PATH 和 EXECUTABLE_ OUTPUT_PATH 变量进行设置即可完成 ; EXECUTABLE_OUTPUT_PATH 变量控制可执行文件的输出路径,而 LIBRARY_OUTPUT_PATH 变量控制库文件的输出路径。

编程小号
上一篇 2025-03-16 17:06
下一篇 2025-03-26 23:21

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/75380.html