工作笔记--CMake使用笔记 配合libmodbus 分别编译出x86的服务器版本和arm的嵌入式linux版本

下载地址 : 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.git
Cloning 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 4580
Receiving 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# ls
acinclude.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  tests
root@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 cmake

root@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 information
project(libmodbus_cmake VERSION 1.0.1 LANGUAGES CXX)

cmake_minimum_required(VERSION 3.1 FATAL_ERROR) #

# Set project information
project(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 found
root@jeason:~/work/libmodbus/build# cmake ..
-- Configuring done
-- Generating done
-- Build files have been written to: /root/work/libmodbus/build
root@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 <config.h>
          ^~~~~~~~~~
compilation terminated.
CMakeFiles/modbus.dir/build.make:62: recipe for target 'CMakeFiles/modbus.dir/src/modbus-data.c.o' failed
make[2]: *** [CMakeFiles/modbus.dir/src/modbus-data.c.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/modbus.dir/all' failed
make[1]: *** [CMakeFiles/modbus.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

运行autogen 和 .config 之后 果然出现了config.h 文件! 运行脚本的过程如下:

root@jeason:~/work/libmodbus# ls
acinclude.m4  autogen.sh  build           cmakes              configure.ac     COPYING.LESSER  ISSUE_TEMPLATE.md  m4           MIGRATION  README.md  tests
AUTHORS       bin         CMakeLists.txt  CODE_OF_CONDUCT.md  CONTRIBUTING.md  doc             libmodbus.pc.in    Makefile.am  NEWS       src
root@jeason:~/work/libmodbus# ./autogen.sh
libtoolize: 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# ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
*****************************************  这里省略很多!!!!!
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating src/modbus-version.h
config.status: creating src/win32/modbus.dll.manifest
config.status: creating tests/Makefile
config.status: creating doc/Makefile
config.status: creating libmodbus.pc
config.status: creating config.h
config.status: creating tests/unit-test.h
config.status: executing depfiles commands
config.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 build
root@jeason:~/work/libmodbus/build# cmake ..
-- Configuring done
-- Generating done
-- Build files have been written to: /root/work/libmodbus/build
root@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 modbus
root@jeason:~/work/libmodbus/build#
root@jeason:~/work/libmodbus/build# ls
CMakeCache.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编进代码中。
在这里插入图片描述=

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值