工作笔记--CMake使用笔记 配合libmodbus 分别编译出x86的服务器版本和arm的嵌入式linux版本
发布日期:2021-06-30 13:42:19 浏览次数:2 分类:技术文章

本文共 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/ubuntu

root@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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:嵌入式linux学习笔记--2021-01-16-- 字符设备驱动开发笔记
下一篇:嵌入式linux 学习笔记--如何使用udhcpc获取动态IP

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月07日 19时30分43秒