Beckhoff Ubuntu ADS库结构、编译与使用优化(像使用OpenCV一样使用ADS库!)

Beckhoff Ubuntu ADS库结构、编译与使用优化

库结构优化

倍福官方的ADS库结构看着不简洁,比较冗余,编译起来效果一般,而且不便于使用

官方ADS库原结构

redwall@redwall-G3-3500:~/3rd_party/ADS$ tree
.
├── AdsLib
│   ├── AdsDef.cpp
│   ├── AdsDef.h
│   ├── AdsDevice.cpp
│   ├── AdsDevice.h
│   ├── AdsException.h
│   ├── AdsFile.cpp
│   ├── AdsFile.h
│   ├── AdsLib.cpp
│   ├── AdsLib.h
│   ├── AdsNotification.h
│   ├── AdsNotificationOOI.h
│   ├── AdsVariable.h
│   ├── AmsConnection.h
│   ├── AmsHeader.h
│   ├── AmsPort.h
│   ├── AmsRouter.h
│   ├── CMakeLists.txt
│   ├── Frame.cpp
│   ├── Frame.h
│   ├── LicenseAccess.cpp
│   ├── LicenseAccess.h
│   ├── Log.cpp
│   ├── Log.h
│   ├── NotificationDispatcher.h
│   ├── RingBuffer.h
│   ├── RouterAccess.cpp
│   ├── RouterAccess.h
│   ├── Router.h
│   ├── RTimeAccess.cpp
│   ├── RTimeAccess.h
│   ├── Semaphore.h
│   ├── Sockets.cpp
│   ├── Sockets.h
│   ├── standalone
│   │   ├── AdsDef.h
│   │   ├── AdsLib.cpp
│   │   ├── AdsLib.h
│   │   ├── AmsConnection.cpp
│   │   ├── AmsNetId.cpp
│   │   ├── AmsPort.cpp
│   │   ├── AmsRouter.cpp
│   │   └── NotificationDispatcher.cpp
│   ├── TwinCAT
│   │   ├── AdsDef.h
│   │   ├── AdsLib.cpp
│   │   └── AdsLib.h
│   ├── wrap_endian.h
│   └── wrap_socket.h
├── AdsLibOOITest
│   └── main.cpp
├── AdsLibTest
│   ├── CMakeLists.txt
│   └── main.cpp
├── AdsLibTestRef
│   └── main.cpp
├── AdsTool
│   ├── main.cpp
│   ├── ParameterList.cpp
│   └── ParameterList.h
├── build
│   ├── AdsLibOOITest
│   ├── AdsLibOOITest@exe
│   │   └── AdsLibOOITest_main.cpp.o
│   ├── AdsLib@sta
│   │   ├── AdsLib_AdsDef.cpp.o
│   │   ├── AdsLib_AdsDevice.cpp.o
│   │   ├── AdsLib_AdsFile.cpp.o
│   │   ├── AdsLib_AdsLib.cpp.o
│   │   ├── AdsLib_Frame.cpp.o
│   │   ├── AdsLib_LicenseAccess.cpp.o
│   │   ├── AdsLib_Log.cpp.o
│   │   ├── AdsLib_RouterAccess.cpp.o
│   │   ├── AdsLib_RTimeAccess.cpp.o
│   │   ├── AdsLib_Sockets.cpp.o
│   │   ├── AdsLib_standalone_AdsLib.cpp.o
│   │   ├── AdsLib_standalone_AmsConnection.cpp.o
│   │   ├── AdsLib_standalone_AmsNetId.cpp.o
│   │   ├── AdsLib_standalone_AmsPort.cpp.o
│   │   ├── AdsLib_standalone_AmsRouter.cpp.o
│   │   └── AdsLib_standalone_NotificationDispatcher.cpp.o
│   ├── AdsLibTest
│   ├── AdsLibTest@exe
│   │   └── AdsLibTest_main.cpp.o
│   ├── adstool
│   ├── adstool@exe
│   │   ├── AdsTool_main.cpp.o
│   │   └── AdsTool_ParameterList.cpp.o
│   ├── build.ninja
│   ├── compile_commands.json
│   ├── libAdsLib.a
│   ├── meson-logs
│   │   └── meson-log.txt
│   └── meson-private
│       ├── build.dat
│       ├── coredata.dat
│       ├── install.dat
│       ├── meson_benchmark_setup.dat
│       ├── meson_test_setup.dat
│       ├── sanitycheckcpp.cc
│       └── sanitycheckcpp.exe
├── CHANGES
├── CMakeLists.txt
├── CONTRIBUTING
├── debian
│   ├── adstool.install
│   ├── changelog
│   ├── compat
│   ├── control
│   ├── copyright
│   ├── libads-dev.install
│   ├── rules
│   └── source
│       └── format
├── doc
│   ├── Makefile
│   └── source
│       ├── adstool.rst
│       ├── conf.py
│       └── index.rst
├── docs
│   ├── Doxyfile
│   └── mainpage.dox
├── example
│   ├── CMakeLists.txt
│   ├── example.cpp
│   ├── Makefile
│   ├── meson.build
│   └── meson_options.txt
├── LICENSE
├── Makefile
├── meson.build
├── meson.cross.amd64-linux.i386
├── meson.cross.amd64-linux.mips
├── meson.cross.amd64-linux.win32
├── meson_options.txt
├── PLC-TestProject
│   ├── _Boot
│   │   └── TwinCAT RT (x86)
│   │       └── Plc
│   │           ├── Port_851.autostart
│   │           ├── Port_851.cid
│   │           └── Port_851.occ
│   ├── NotificationTest.sln
│   ├── NotificationTest.tsproj
│   └── Untitled1
│       ├── ExternalTypes.tmc
│       ├── _Libraries
│       │   └── beckhoff automation gmbh
│       │       ├── tc2_standard
│       │       │   └── 3.3.0.0
│       │       │       └── tc2_standard.compiled-library
│       │       ├── tc2_system
│       │       │   └── 3.3.8.1
│       │       │       └── tc2_system.compiled-library
│       │       ├── tc3_interfaces
│       │       │   └── 3.3.0.0
│       │       │       └── tc3_interfaces.compiled-library
│       │       └── tc3_module
│       │           └── 3.3.6.0
│       │               └── tc3_module.compiled-library
│       ├── PlcTask.TcTTO
│       ├── POUs
│       │   └── MAIN.TcPOU
│       ├── Untitled1.plcproj
│       └── Untitled1.tpy
├── README
└── tools
    ├── 10_get_fructose.sh
    ├── 80_ads_route.sh
    ├── 90_run_tests.sh
    ├── 91_test_AdsTool.sh
    ├── add-route.py
    ├── canonicalize_filename.sh
    ├── fructose
    │   ├── double_compare.h
    │   ├── fructose.h
    │   ├── test_base.h
    │   └── test_root.h
    ├── fructose-1.4.0.sha512
    ├── pre-commit.settings
    ├── pre-commit.uncrustify
    └── uncrustify.cfg

38 directories, 145 files

实际上我们编程控制时只会用到AdsLib文件夹下的内容,对AdsLib目录下的文件整理即可

经调整后的结构,h文件归入include文件夹,cpp文件归入src文件夹,二进制文件归入bin文件夹,库文件归入lib文件夹,这样比较符合规范

redwall@redwall-G3-3500:~/3rd_party/AdsLib$ tree
.
├── ADSConfig.cmake
├── bin
├── build
├── CMakeLists.txt
├── go.sh
├── include
│   ├── AdsDef.h
│   ├── AdsDevice.h
│   ├── AdsException.h
│   ├── AdsFile.h
│   ├── AdsLib.h
│   ├── AdsNotification.h
│   ├── AdsNotificationOOI.h
│   ├── AdsVariable.h
│   ├── AmsConnection.h
│   ├── AmsHeader.h
│   ├── AmsPort.h
│   ├── AmsRouter.h
│   ├── Frame.h
│   ├── LicenseAccess.h
│   ├── Log.h
│   ├── NotificationDispatcher.h
│   ├── RingBuffer.h
│   ├── RouterAccess.h
│   ├── Router.h
│   ├── RTimeAccess.h
│   ├── Semaphore.h
│   ├── Sockets.h
│   ├── wrap_endian.h
│   └── wrap_socket.h
├── lib
├── src
│   ├── AdsDef.cpp
│   ├── AdsDevice.cpp
│   ├── AdsFile.cpp
│   ├── AdsLib.cpp
│   ├── Frame.cpp
│   ├── LicenseAccess.cpp
│   ├── Log.cpp
│   ├── RouterAccess.cpp
│   ├── RTimeAccess.cpp
│   └── Sockets.cpp
├── standalone
│   ├── AdsDef.h
│   ├── AdsLib.cpp
│   ├── AdsLib.h
│   ├── AmsConnection.cpp
│   ├── AmsNetId.cpp
│   ├── AmsPort.cpp
│   ├── AmsRouter.cpp
│   └── NotificationDispatcher.cpp
└── TwinCAT
    ├── AdsDef.h
    ├── AdsLib.cpp
    └── AdsLib.h

7 directories, 48 files

编译优化

AdsLib文件夹下原版的CMakeLists.txt内容如下

set(SOURCES
  AdsDef.cpp
  AdsDevice.cpp
  AdsFile.cpp
  AdsLib.cpp
  Frame.cpp
  LicenseAccess.cpp
  Log.cpp
  RouterAccess.cpp
  RTimeAccess.cpp
  Sockets.cpp

  standalone/AdsLib.cpp
  standalone/AmsConnection.cpp
  standalone/AmsNetId.cpp
  standalone/AmsPort.cpp
  standalone/AmsRouter.cpp
  standalone/NotificationDispatcher.cpp
)

add_library(ads ${
    
    SOURCES})

target_include_directories(ads PUBLIC .)

if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  target_link_libraries(ads PUBLIC wsock32)
endif()

if(WIN32 EQUAL 1)
    target_link_libraries(ads PUBLIC ws2_32)
endif()

target_link_libraries(ads PUBLIC Threads::Threads)

有一个错误是Thread在Linux下是找不到的,因此编译时会报错

ADS文件夹下原版的CMakeLists.txt内容如下

cmake_minimum_required(VERSION 3.10.2)

project(ads)

find_package(Threads)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  set(COMPILE_OPTIONS
    -pedantic
    -Wall
    -Wextra
  )
  add_definitions(-D_GNU_SOURCE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  # Compiler flags and definitions for Visual Studio come here
endif()

option(BUILD_SHARED_LIBS "Build using shared libraries" ON)

add_subdirectory(AdsLib)
add_subdirectory(AdsLibTest)
add_subdirectory(example)

官方提供的编译指导

# clone the repository
git clone https://github.com/Beckhoff/ADS.git
# change into root of the cloned repository
cd ADS
# configure meson to build the library into "build" dir
meson setup build
# let ninja build the library
ninja -C build

看到编译后只在build目录下存在一个libAdsLib.a的静态库

在这里插入图片描述

首先在别的程序中链接到这个静态库就不方便,其次静态库每次使用都要生成一遍副本,占内存

比较好的处理应当是只编译一次AdsLib,将头文件安装到系统中,生成一份动态库,这样头文件的引入和库文件的链接都会清晰很多

直接上优化后的CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(adslib)

include_directories(${
    
    PROJECT_SOURCE_DIR}/include)
include_directories(${
    
    PROJECT_SOURCE_DIR}/standalone)

set(SOURCES
  src/AdsDef.cpp
  src/AdsDevice.cpp
  src/AdsFile.cpp
  src/AdsLib.cpp
  src/Frame.cpp
  src/LicenseAccess.cpp
  src/Log.cpp
  src/RouterAccess.cpp
  src/RTimeAccess.cpp
  src/Sockets.cpp

  standalone/AdsLib.cpp
  standalone/AmsConnection.cpp
  standalone/AmsNetId.cpp
  standalone/AmsPort.cpp
  standalone/AmsRouter.cpp
  standalone/NotificationDispatcher.cpp
)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")

set(EXECUTABLE_OUTPUT_PATH ${
    
    PROJECT_SOURCE_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${
    
    PROJECT_SOURCE_DIR}/lib)

add_library(ads SHARED ${
    
    SOURCES})

if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  target_link_libraries(ads PUBLIC wsock32)
endif()

if(WIN32 EQUAL 1)
  target_link_libraries(ads PUBLIC ws2_32)
endif()

set(INSTALL_INCLUDE_DIR /usr/local/include/ads)
install(DIRECTORY ${
    
    PROJECT_SOURCE_DIR}/include/
  DESTINATION ${
    
    INSTALL_INCLUDE_DIR}/include/
  FILES_MATCHING PATTERN "*.h")
install(DIRECTORY ${
    
    PROJECT_SOURCE_DIR}/standalone/
  DESTINATION ${
    
    INSTALL_INCLUDE_DIR}/standalone/
  FILES_MATCHING PATTERN "*.h")

set(CMAKE_INSTALL_PREFIX /usr/local)
install(TARGETS ads
  LIBRARY DESTINATION ${
    
    CMAKE_INSTALL_PREFIX}/lib)

1、thread的错误用-pthread处理

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")

2、将包含头文件的文件夹include进来

include_directories(${
    
    PROJECT_SOURCE_DIR}/include)
include_directories(${
    
    PROJECT_SOURCE_DIR}/standalone)

3、设置可执行文件输出路径和库文件输出路径

set(EXECUTABLE_OUTPUT_PATH ${
    
    PROJECT_SOURCE_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${
    
    PROJECT_SOURCE_DIR}/lib)

4、设置待编译源文件,并编译为动态库

set(SOURCES
  src/AdsDef.cpp
  src/AdsDevice.cpp
  src/AdsFile.cpp
  src/AdsLib.cpp
  src/Frame.cpp
  src/LicenseAccess.cpp
  src/Log.cpp
  src/RouterAccess.cpp
  src/RTimeAccess.cpp
  src/Sockets.cpp

  standalone/AdsLib.cpp
  standalone/AmsConnection.cpp
  standalone/AmsNetId.cpp
  standalone/AmsPort.cpp
  standalone/AmsRouter.cpp
  standalone/NotificationDispatcher.cpp
)

add_library(ads SHARED ${
    
    SOURCES})

5、设置头文件安装路径并安装头文件

set(INSTALL_INCLUDE_DIR /usr/local/include/ads)
install(DIRECTORY ${
    
    PROJECT_SOURCE_DIR}/include/
  DESTINATION ${
    
    INSTALL_INCLUDE_DIR}/include/
  FILES_MATCHING PATTERN "*.h")
install(DIRECTORY ${
    
    PROJECT_SOURCE_DIR}/standalone/
  DESTINATION ${
    
    INSTALL_INCLUDE_DIR}/standalone/
  FILES_MATCHING PATTERN "*.h")

6、设置库文件安装路径并安装库文件

set(CMAKE_INSTALL_PREFIX /usr/local)
install(TARGETS ads
  LIBRARY DESTINATION ${
    
    CMAKE_INSTALL_PREFIX}/lib)

这样就会将include和standalone下的头文件安装到/usr/local/include/ads目录下,动态库会现在lib文件夹下生成一份,然后再安装到/usr/local/lib文件夹下

redwall@redwall-G3-3500:/usr/local/include/ads$ tree
.
├── include
│   ├── AdsDef.h
│   ├── AdsDevice.h
│   ├── AdsException.h
│   ├── AdsFile.h
│   ├── AdsLib.h
│   ├── AdsNotification.h
│   ├── AdsNotificationOOI.h
│   ├── AdsVariable.h
│   ├── AmsConnection.h
│   ├── AmsHeader.h
│   ├── AmsPort.h
│   ├── AmsRouter.h
│   ├── Frame.h
│   ├── LicenseAccess.h
│   ├── Log.h
│   ├── NotificationDispatcher.h
│   ├── RingBuffer.h
│   ├── RouterAccess.h
│   ├── Router.h
│   ├── RTimeAccess.h
│   ├── Semaphore.h
│   ├── Sockets.h
│   ├── wrap_endian.h
│   └── wrap_socket.h
└── standalone
    ├── AdsDef.h
    └── AdsLib.h

2 directories, 26 files
redwall@redwall-G3-3500:/usr/local/lib$ ls | grep liba
libads.so

使用优化

上述操作后ADS库用起来会方便很多,比如ADS通信测试程序link_test的CMakeLists.txt如下

cmake_minimum_required(VERSION 3.10)
project(ads_test)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")

set(EXECUTABLE_OUTPUT_PATH ${
    
    PROJECT_SOURCE_DIR}/bin)
include_directories(${
    
    PROJECT_SOURCE_DIR}/include)

include_directories(/usr/local/include/ads)

#添加测试程序
add_executable(link_test src/link_test.cpp)
target_link_libraries(link_test libads.so)

引入头文件和链接动态库操作如下

include_directories(/usr/local/include/ads)
target_link_libraries(link_test libads.so)

还要记下路径和动态库名,不是很优雅,更好的应该是像使用OpenCV那样

find_package(OpenCV REQUIRED)

include_directories(${
    
    OpenCV_INCLUDE_DIRS})

add_executable(my_program main.cpp)
target_link_libraries(my_program ${
    
    OpenCV_LIBRARIES})

那要怎么做呢,这一步我折腾了很久,尝试了很多方法

写了FindADS.cmake文件,并cp到/usr/share/cmake-3.10/Modules/

set(PACKAGE_NAME ADS)
set(PACEAGE_VERSION 1.0)

set(HEADER_PATH /usr/local/include/ads/include)
find_path(PACKAGE_INCLUDE_DIR AdsDevice.h PATHS ${
    
    HEADER_PATH})
if(NOT PACKAGE_INCLUDE_DIR)
    message(FATAL_ERROR "Failed to find ${PACKAGE_NAME} headers!")
endif()

set(LIBRARY_PATH /usr/local/lib)
find_library(PACKAGE_LIBRARY ads NAMES libads.so PATHS ${
    
    LIBRARY_PATH})
if(NOT PACKAGE_LIBRARY)
    message(FATAL_ERROR "Failed to find ${PACKAGE_NAME} libraries!")
endif()

# set(PACKAGE_LIBRARY /usr/local/lib/libads.so)

set(PACKAGE_FOUND TRUE)
message(STATUS "Found ${PACKAGE_NAME}: ${PACKAGE_INCLUDE_DIR}")
message(STATUS "Found ${PACKAGE_NAME}: ${PACKAGE_LIBRARY}")

set(PACKAGE_INCLUDE_DIRS ${
    
    PACKAGE_INCLUDE_DIR})
set(PACKAGE_LIBRARIES ${
    
    PACKAGE_LIBRARY})
set(PACEAGE_VERSION ${
    
    PACEAGE_VERSION})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(${
    
    PACKAGE_NAME} REQUIRED_VARS PACKAGE_INCLUDE_DIRS PACKAGE_LIBRARIES)

但是每次编译的时候都会报错,无法正确链接到libads.so动态库

几乎快放弃了,我在想FindADS.cmake的目的就是确定头文件路径以及动态库位置,那么既然预先已经指定安装位置,那么有没有办法直接从外部文件中引入包含该位置的变量

这里涉及到几个问题:

1、CMakeLists.txt如何引入外部文件的变量

可以使用 include() 命令来引入外部文件,并且使用 set() 命令来定义变量

例如,假设有一个 config.cmake 文件,里面定义了一个名为 MY_VAR 的变量

set(MY_VAR "Hello, world!")

可以在 CMakeLists.txt 文件中使用 include() 命令来引入这个文件,并使用 ${MY_VAR} 来获取变量的值

cmake_minimum_required(VERSION 3.10)

project(MyProject)

include(config.cmake)

message(STATUS "MY_VAR is: ${MY_VAR}")

当执行 CMake 时,它会读取 config.cmake 文件并将其中定义的变量加载到当前 CMakeLists.txt 中,从而可以在后面的命令中使用这些变量

2、怎么在 CMakeLists.txt 中找.cmake文件

在CMakeLists.txt中使用**include()命令来引入其他的.cmake文件。这个命令会将被包含文件中的代码插入到当前文件中,类似于将一个头文件包含到源代码中一样。例如,如果想引入一个名为MyLibraryConfig.cmake**的配置文件,可以使用以下命令

include(MyLibraryConfig.cmake)

这样,CMake将在当前目录下查找名为**MyLibraryConfig.cmake**的文件,并将其中的代码插入到当前的CMakeLists.txt文件中

3、CMakeLists.txt只能在当前目录查找.cmake文件吗

不完全是,默认情况下,CMake会首先在当前目录查找.cmake文件,但是还可以使用CMAKE_MODULE_PATH变量将其他目录添加到模块搜索路径中

例如,以下代码将添加名为“cmake”子目录的路径,以便CMake可以在其中查找模块文件

set(CMAKE_MODULE_PATH ${
    
    CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

这将在当前源目录下的名为“cmake”的子目录中搜索模块文件

4、CMakeLists.txt能否通过名称查找.cmake文件

是的,CMakeLists.txt可以通过名称查找.cmake文件。CMake提供了一个名为**find_package()的命令,它可以搜索和加载外部包。如果这个包提供了一个<PackageName>Config.cmake文件,那么CMake就可以使用这个文件来配置项目。<PackageName>Config.cmake**文件通常包含了该包的构建和安装信息,以及包含的库的信息

**find_package()会查找<PackageName>Config.cmake文件的位置,如果找到就会加载该文件并解析其内容,从而完成包的配置。如果该文件没有找到,CMake就会尝试使用其他的查找机制,比如使用Find<PackageName>.cmake文件,或者直接使用find_library()**等命令

通常,**<PackageName>Config.cmake文件应该被安装到系统的标准位置中。如果该文件没有被安装到标准位置中,就需要在使用find_package()命令时手动指定该文件的路径,或者通过设置CMAKE_PREFIX_PATH**变量来告诉CMake该文件的位置

例如,如果要搜索名为**Foo**的包,可以这样写

find_package(Foo REQUIRED)

如果该包提供了**FooConfig.cmake文件,CMake就会在标准位置中搜索该文件,并使用它来配置项目。如果该文件没有找到,CMake就会尝试使用FindFoo.cmake**文件进行搜索,或者使用其他的查找机制

5、Config.cmake文件应该被安装到系统的标准位置中,标准位置是哪里

通常情况下,Config.cmake文件应该被安装到系统的标准位置中,即**<prefix>/lib/<PackageName>/cmake/<PackageName>Config.cmake**

其中,<prefix>是安装时指定的CMAKE_INSTALL_PREFIX的路径。如果在编译库时没有显式指定CMAKE_INSTALL_PREFIX,则默认安装到**/usr/local/**目录下


猜一猜这些问答式的记录如何来的,Bingo,当然是问万能的chatGPT啦

通过上面的5个问答可以帮我们捋清思路

1、首先我们的功能包名为ADS,那么需要编辑一个ADSConfig.cmake文件

在文件中直接指定头文件路径和动态库位置

set(ADS_INCLUDE_DIRS /usr/local/include/ads)
set(ADS_LIBRARIES /usr/local/lib/libads.so)

2、然后我们将该.cmake文件安装到系统的标准位置,首先要新建目录,在cp过去

sudo mkdir /usr/local/lib/cmake/ADS
sudo cp ADSConfig.cmake /usr/local/lib/cmake/ADS

3、最后我们便可以像使用OpenCV一样使用ADS库,注意是CONFIG而不是REQUIRED

find_package(ADS CONFIG)
include_directories(${
    
    ADS_INCLUDE_DIRS})

target_link_libraries(link_test ${
    
    ADS_LIBRARIES})

优化后ADS通信测试程序link_test的CMakeLists.txt如下

cmake_minimum_required(VERSION 3.10)
project(ads_test)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")

set(EXECUTABLE_OUTPUT_PATH ${
    
    PROJECT_SOURCE_DIR}/bin)
include_directories(${
    
    PROJECT_SOURCE_DIR}/include)

find_package(ADS CONFIG)
include_directories(${
    
    ADS_INCLUDE_DIRS})

#添加测试程序
add_executable(link_test src/link_test.cpp)
target_link_libraries(link_test ${
    
    ADS_LIBRARIES})

Elegant!

后话

在Ubuntu下完整的优化后的Beckhoff ADS库已经托管到了个人仓库

GitHub仓库:Beckhoff_Ubuntu_ADS_Library

Gitee仓库:Beckhoff_Ubuntu_ADS_Library

还提供了一键编译安装的脚本go.sh

#!/bin/bash
echo "Begin build ADS Library"
echo "-----------------------------------"
cd build
cmake ..
make -j4

echo -e "\nBegin install ADS Library"
echo "-----------------------------------"
sudo make install

echo -e "\nConfig ADS CMake"
echo "-----------------------------------"
sudo mkdir /usr/local/lib/cmake/ADS
sudo cp ../ADSConfig.cmake /usr/local/lib/cmake/ADS

首先要为脚本添加可执行权限,运行脚本需要root权限,因此要加sudo

sudo chmod +x go.sh
sudo ./go.sh
redwall@redwall-G3-3500:~/3rd_party/AdsLib$ sudo ./go.sh 
[sudo] redwall 的密码: 
Begin build ADS Library
-----------------------------------
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/redwall/3rd_party/AdsLib/build
Scanning dependencies of target ads
[ 23%] Building CXX object CMakeFiles/ads.dir/src/AdsLib.cpp.o
[ 23%] Building CXX object CMakeFiles/ads.dir/src/AdsFile.cpp.o
[ 23%] Building CXX object CMakeFiles/ads.dir/src/AdsDef.cpp.o
[ 23%] Building CXX object CMakeFiles/ads.dir/src/AdsDevice.cpp.o
[ 29%] Building CXX object CMakeFiles/ads.dir/src/Frame.cpp.o
[ 35%] Building CXX object CMakeFiles/ads.dir/src/LicenseAccess.cpp.o
[ 41%] Building CXX object CMakeFiles/ads.dir/src/Log.cpp.o
[ 47%] Building CXX object CMakeFiles/ads.dir/src/RouterAccess.cpp.o
[ 52%] Building CXX object CMakeFiles/ads.dir/src/RTimeAccess.cpp.o
[ 58%] Building CXX object CMakeFiles/ads.dir/src/Sockets.cpp.o
[ 64%] Building CXX object CMakeFiles/ads.dir/standalone/AdsLib.cpp.o
[ 70%] Building CXX object CMakeFiles/ads.dir/standalone/AmsConnection.cpp.o
[ 76%] Building CXX object CMakeFiles/ads.dir/standalone/AmsNetId.cpp.o
[ 82%] Building CXX object CMakeFiles/ads.dir/standalone/AmsPort.cpp.o
[ 88%] Building CXX object CMakeFiles/ads.dir/standalone/AmsRouter.cpp.o
[ 94%] Building CXX object CMakeFiles/ads.dir/standalone/NotificationDispatcher.cpp.o
[100%] Linking CXX shared library ../lib/libads.so
[100%] Built target ads

Begin install ADS Library
-----------------------------------
[100%] Built target ads
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/include/ads/include/
-- Installing: /usr/local/include/ads/include//Frame.h
-- Installing: /usr/local/include/ads/include//AdsNotificationOOI.h
-- Installing: /usr/local/include/ads/include//wrap_socket.h
-- Installing: /usr/local/include/ads/include//AdsDevice.h
-- Installing: /usr/local/include/ads/include//AmsPort.h
-- Installing: /usr/local/include/ads/include//wrap_endian.h
-- Installing: /usr/local/include/ads/include//Router.h
-- Installing: /usr/local/include/ads/include//RingBuffer.h
-- Installing: /usr/local/include/ads/include//Semaphore.h
-- Installing: /usr/local/include/ads/include//AmsRouter.h
-- Installing: /usr/local/include/ads/include//AdsFile.h
-- Installing: /usr/local/include/ads/include//Sockets.h
-- Installing: /usr/local/include/ads/include//AdsDef.h
-- Installing: /usr/local/include/ads/include//NotificationDispatcher.h
-- Installing: /usr/local/include/ads/include//AmsHeader.h
-- Installing: /usr/local/include/ads/include//AdsVariable.h
-- Installing: /usr/local/include/ads/include//AdsNotification.h
-- Installing: /usr/local/include/ads/include//AdsException.h
-- Installing: /usr/local/include/ads/include//LicenseAccess.h
-- Installing: /usr/local/include/ads/include//AdsLib.h
-- Installing: /usr/local/include/ads/include//RouterAccess.h
-- Installing: /usr/local/include/ads/include//AmsConnection.h
-- Installing: /usr/local/include/ads/include//Log.h
-- Installing: /usr/local/include/ads/include//RTimeAccess.h
-- Installing: /usr/local/include/ads/standalone/
-- Installing: /usr/local/include/ads/standalone//AdsDef.h
-- Installing: /usr/local/include/ads/standalone//AdsLib.h
-- Installing: /usr/local/lib/libads.so

Config ADS CMake
-----------------------------------
redwall@redwall-G3-3500:~/Test/ADS_test/build$ make
-- Configuring done
-- Generating done
-- Build files have been written to: /home/redwall/Test/ADS_test/build
Scanning dependencies of target link_test
[ 50%] Building CXX object CMakeFiles/link_test.dir/src/link_test.cpp.o
[100%] Linking CXX executable ../bin/link_test
[100%] Built target link_test

运行完脚本后就可以直接像使用OpenCV一样使用ADS库啦,大家快用起来吧,欢迎star

猜你喜欢

转载自blog.csdn.net/Solititude/article/details/129613935
今日推荐