本文共 7633 字,大约阅读时间需要 25 分钟。
下载地址 : https://gitee.com/jeasonb/libmodbus_cmake_test
工作以来用到cmake 已经半年了,现在愈发的感觉到cmake 的强大,今天拿出一些时间将之前用到的一些cmake 的功能整理一下,方便之后自己查阅,同时也给后来者一个参考。
我们使用cmake 大多都是用来编译项目、库等等的用途,接下来我会以libmodbu库为基础介绍如何使用cmake 以及这个开源库用到了cmake 的一些什么功能!
预计将会用cmake 编译libmodbus 库以及测试工程到服务器(x86 在公网)版本 和 嵌入式linux 版本(韦东山老师的imx6ull)1. 第一步下载到源码
root@jeason:~/work# git clone https://github.com/stephane/libmodbus.gitCloning into 'libmodbus'...remote: Enumerating objects: 16, done.remote: Counting objects: 100% (16/16), done.remote: Compressing objects: 100% (12/12), done.remote: Total 4596 (delta 4), reused 7 (delta 4), pack-reused 4580Receiving objects: 100% (4596/4596), 1.52 MiB | 29.00 KiB/s, done.Resolving deltas: 100% (3112/3112), done.root@jeason:~/work# cd libmodbus/root@jeason:~/work/libmodbus# lsacinclude.m4 AUTHORS autogen.sh CODE_OF_CONDUCT.md configure.ac CONTRIBUTING.md COPYING.LESSER doc ISSUE_TEMPLATE.md libmodbus.pc.in m4 Makefile.am MIGRATION NEWS README.md src testsroot@jeason:~/work/libmodbus#
2. 打开源码分析
这里我使用的是给服务器装上zerotier 然后和本地的电脑组成虚拟局域网 在虚拟局域网开samba,这样我的电脑就能直接访问到服务器上的文件了。这个无关紧要。总之你要能访问到你自己下载的文件。
观察源码 我们不难发现这个开源项目是给了一个 一键执行脚本的!,所以 我们服务端的升级可以直接运行意见脚本 编译安装库文件,但是 本节主要是记录cmake 的用法,所以还是直接忽略吧,不能偷懒!
分析一下各个目录的用途: docs 很明显这个目录就是放置各种的使用说明文档的,libmodbus 库非常的友好,所有的api 的说明文档一应俱全! 参考以下图片 这是其中一个API的介绍 介绍了函数原型以及各个参数的意思 m4 路径不知道是干什么用的,所以暂时就不去班门弄斧了,之前的实际项目中也没有用到这个目录src 目录下就是 各种的库函数的接口,在我们的实际应用中就是把这一部分编译为一个动态库,嵌入式系统在使用的时候就加载这个库文件,这一部分的文件不多 只有那么少数的几个文件!
接着就是test 文件夹了,这个文件夹下面放的是大家喜闻乐见的参考demo ,我的第一个程序也是跑test 来的,有点类似于hello world最后就是 最外层的各种文件,开源协议等等的文件以及readme 文件,介绍了一些更新记录已知的bug 以及记录了一些牛x的贡献者,向大佬们致敬。
所以我们今天要做的就是创建一个cmake 工程把libmodbus 库 从代码变为可以在不同平台上执行的可执行程序!
3. 创建cmake 工程
使用之前不要忘了装上cmake!
linux 下 (没换源的建议换源!)参考链接https://developer.aliyun.com/mirror/ubunturoot@jeason:~/work/libmodbus/build# cmake ..Command 'cmake' not found, but can be installed with:apt install cmakeroot@jeason:~/work/libmodbus/build# sudo apt install cmake
在工程顶层 创建以下几个目录
build – 存放编译中间文件 bin – 存放编译生成的最终文件 cmake – 存放cmake 配置文件 CMakeLists.txt – cmake配置文件 具体如何称呼不知道,就是用于之后生成makefile 的然后将之前的一份测试的cmake 复制进去,测试的cmake大概是这样的
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)# Set project informationproject(libmodbus_cmake VERSION 1.0.1 LANGUAGES CXX)cmake_minimum_required(VERSION 3.1 FATAL_ERROR) ## Set project informationproject(libmodbus LANGUAGES C) # 设置语言include(cmakes/BuildDefaults.cmake) #一些编译选项 类似于配置的头文件 include_directories( #添加头文件包含路径 . ./src/)add_library(modbus SHARED #关键步骤,设置动态库的文件 ./src/modbus-data.c ./src/modbus-tcp.c ./src/modbus-rtu.c ./src/modbus.c)include_directories("${PROJECT_SOURCE_DIR}/src/")
编译之后会发现 我们缺少一个配置文件! config.h
这种情况就是因为我们没有按照官方的步骤 运行官方的脚本生成config.h 文件! 那么 就运行一下试试呗 缺少config的报错如下:root@jeason:~/work/libmodbus/build# cmake..cmake..: command not foundroot@jeason:~/work/libmodbus/build# cmake ..-- Configuring done-- Generating done-- Build files have been written to: /root/work/libmodbus/buildroot@jeason:~/work/libmodbus/build# make[ 20%] Building C object CMakeFiles/modbus.dir/src/modbus-data.c.o/root/work/libmodbus/src/modbus-data.c:24:10: fatal error: config.h: No such file or directory #include^~~~~~~~~~compilation terminated.CMakeFiles/modbus.dir/build.make:62: recipe for target 'CMakeFiles/modbus.dir/src/modbus-data.c.o' failedmake[2]: *** [CMakeFiles/modbus.dir/src/modbus-data.c.o] Error 1CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/modbus.dir/all' failedmake[1]: *** [CMakeFiles/modbus.dir/all] Error 2Makefile:83: recipe for target 'all' failedmake: *** [all] Error 2
运行autogen 和 .config 之后 果然出现了config.h 文件! 运行脚本的过程如下:
root@jeason:~/work/libmodbus# lsacinclude.m4 autogen.sh build cmakes configure.ac COPYING.LESSER ISSUE_TEMPLATE.md m4 MIGRATION README.md testsAUTHORS bin CMakeLists.txt CODE_OF_CONDUCT.md CONTRIBUTING.md doc libmodbus.pc.in Makefile.am NEWS srcroot@jeason:~/work/libmodbus# ./autogen.shlibtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'build-aux'.libtoolize: linking file 'build-aux/ltmain.sh'libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.libtoolize: linking file 'm4/libtool.m4'libtoolize: linking file 'm4/ltoptions.m4'libtoolize: linking file 'm4/ltsugar.m4'libtoolize: linking file 'm4/ltversion.m4'libtoolize: linking file 'm4/lt~obsolete.m4'configure.ac:33: installing 'build-aux/compile'configure.ac:56: installing 'build-aux/config.guess'configure.ac:56: installing 'build-aux/config.sub'configure.ac:32: installing 'build-aux/install-sh'configure.ac:32: installing 'build-aux/missing'src/Makefile.am: installing 'build-aux/depcomp'parallel-tests: installing 'build-aux/test-driver'------------------------------------------------------Initialized build system. You can now run ./configure------------------------------------------------------root@jeason:~/work/libmodbus# ./configurechecking for a BSD-compatible install... /usr/bin/install -cchecking whether build environment is sane... yeschecking for a thread-safe mkdir -p... /bin/mkdir -pchecking for gawk... gawk***************************************** 这里省略很多!!!!!configure: creating ./config.statusconfig.status: creating Makefileconfig.status: creating src/Makefileconfig.status: creating src/modbus-version.hconfig.status: creating src/win32/modbus.dll.manifestconfig.status: creating tests/Makefileconfig.status: creating doc/Makefileconfig.status: creating libmodbus.pcconfig.status: creating config.hconfig.status: creating tests/unit-test.hconfig.status: executing depfiles commandsconfig.status: executing libtool commands libmodbus 3.1.6 =============== prefix: /usr/local sysconfdir: ${prefix}/etc libdir: ${exec_prefix}/lib includedir: ${prefix}/include compiler: gcc cflags: -g -O2 ldflags: documentation: no tests: yes
观察这个 config.h 可以发现主要就是一些配置项 应该是之后生成可执行文件的编译前提,我们先不去管它,先用默认的编译出服务器版本的。
此时已经可以使用cmake 编译出动态库文件了root@jeason:~/work/libmodbus# cd buildroot@jeason:~/work/libmodbus/build# cmake ..-- Configuring done-- Generating done-- Build files have been written to: /root/work/libmodbus/buildroot@jeason:~/work/libmodbus/build#root@jeason:~/work/libmodbus/build#root@jeason:~/work/libmodbus/build#root@jeason:~/work/libmodbus/build# make[ 20%] Building C object CMakeFiles/modbus.dir/src/modbus-data.c.o[ 40%] Building C object CMakeFiles/modbus.dir/src/modbus-tcp.c.o/root/work/libmodbus/src/modbus-tcp.c: In function ‘modbus_tcp_accept’:/root/work/libmodbus/src/modbus-tcp.c:672:14: warning: implicit declaration of function ‘accept4’; did you mean ‘accept’? [-Wimplicit-function-declaration] ctx->s = accept4(*s, (struct sockaddr *)&addr, &addrlen, SOCK_CLOEXEC); ^~~~~~~ accept[ 60%] Building C object CMakeFiles/modbus.dir/src/modbus-rtu.c.o[ 80%] Building C object CMakeFiles/modbus.dir/src/modbus.c.o[100%] Linking C shared library libmodbus.so[100%] Built target modbusroot@jeason:~/work/libmodbus/build#root@jeason:~/work/libmodbus/build# lsCMakeCache.txt CMakeFiles cmake_install.cmake libmodbus.so Makefile
此时已经编译出来了 动态库文件 libmodbus.so
接下来 使用以下语句让编译文件定向输出到bin文件下set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) #设置 编译输出文件的位置 CMAKE_RUNTIME_OUTPUT_DIRECTORY是内置宏定义
接下来编译一个简单的测试程序
通过添加 上面标红的代码段 可以生成服务器上的可执行文件。 接下来通过修改 gcc 编译器为交叉编译器可以生成 嵌入式设备上的可执行文件 对应的代码段如下图所示:(注意:笔者环境中已经将 编译器加入环境变量,如果没有添加环境变量也可以直接使用 编译器的绝对路径) 将生成的libmodbus.so 拷贝到开发板的 /lib路径 然后将client_test 加执行权限之后运行, 笔者这里直接将服务器公网IP编进代码中。 =转载地址:https://jeason.blog.csdn.net/article/details/112427705 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!