CMake与动态链接库(dll, so, dylib)

来源:互联网 发布:二维坐标系转换矩阵 编辑:程序博客网 时间:2024/04/30 23:54

使用CMake可以很方便的实现跨平台编译。如果要Link一个第三方库,需要针对平台进行设置。这里分享下如何创建一个简单的CMake工程实现Windows, Linux和macOS上的自动编译。

SDK下载

  • Dynamsoft Barcode Reader 5.2 for Windows
  • Dynamsoft Barcode Reader 5.2 for Linux
  • Dynamsoft Barcode Reader 5.2 for macOS

CMake下载安装

Windows

  • Visual Studio Community 2017
  • cmake-3.9.5-win64-x64.msi

Linux

sudo apt-get install cmake

macOS

brew install cmake

注意不要在brew前面加sudo。最新的brew不再支持,用了会发生错误:

Error: Running Homebrew as root is extremely dangerous and no longer supported.As Homebrew does not drop privileges on installation you would be giving allbuild scripts full access to your system.

工程结构

project    |-- platforms        |-- win            |-- DBRx86.lib            |-- DynamsoftBarcodeReaderx86.dll        |-- linux            |-- libDynamsoftBarcodeReader.so        |-- macos            |-- libDynamsoftBarcodeReader.dylib    |-- include        |-- DynamsoftBarcodeReader.h    |-- BarcodeReader.cxx    |-- BarcodeReaderConfig.h.in    |-- CMakeLists.txt

C++代码

写了一个简单的命令行barcode reader。这里的重点是如何配置CMake,代码不解释。
可以浏览BarcodeReader.cxx

CMakeLists.txt

平台区分

if (CMAKE_HOST_WIN32)    set(WINDOWS 1)elseif(CMAKE_HOST_APPLE)    set(MACOS 1)elseif(CMAKE_HOST_UNIX)    set(LINUX 1)endif()

设置动态链接库路径

if(WINDOWS)    link_directories("${PROJECT_SOURCE_DIR}/platforms/win") elseif(LINUX)    link_directories("${PROJECT_SOURCE_DIR}/platforms/linux") elseif(MACOS)    link_directories("${PROJECT_SOURCE_DIR}/platforms/macos") endif()

Windows上拷贝dll文件到输出目录

if(WINDOWS)    # Copy DLL files to output directory    if(CMAKE_CL_64)        add_custom_command(TARGET BarcodeReader POST_BUILD         COMMAND ${CMAKE_COMMAND} -E copy_if_different        "${PROJECT_SOURCE_DIR}/platforms/win/DynamsoftBarcodeReaderx64.dll"                      $<TARGET_FILE_DIR:BarcodeReader>)    else()        add_custom_command(TARGET BarcodeReader POST_BUILD         COMMAND ${CMAKE_COMMAND} -E copy_if_different        "${PROJECT_SOURCE_DIR}/platforms/win/DynamsoftBarcodeReaderx86.dll"                      $<TARGET_FILE_DIR:BarcodeReader>)    endif()endif()

设置安装路径

if(WINDOWS)    set(CMAKE_INSTALL_PREFIX "e:/${PROJECT_NAME}")    if(CMAKE_CL_64)    install (FILES "${PROJECT_SOURCE_DIR}/platforms/win/DynamsoftBarcodeReaderx64.dll" DESTINATION bin)    else()    install (FILES "${PROJECT_SOURCE_DIR}/platforms/win/DynamsoftBarcodeReaderx86.dll" DESTINATION bin)    endif()elseif(LINUX)    install (FILES "${PROJECT_SOURCE_DIR}/platforms/linux/libDynamsoftBarcodeReader.so" DESTINATION lib)elseif(MACOS)    install (FILES "${PROJECT_SOURCE_DIR}/platforms/macos/libDynamsoftBarcodeReader.dylib" DESTINATION lib)endif()

在Windows上默认会安装到C盘,如果命令行工具没有管理员权限会安装失败。所以可以更改默认安装路径。

设置RPATH

# Set RPATHif(WINDOWS)else()    set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")    MESSAGE( STATUS "CMAKE_INSTALL_RPATH: " "${CMAKE_INSTALL_PREFIX}/lib" )    set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)endif()

Linux和macOS上的默认路径是/usr/local。安装之后执行程序会找不到动态链接库。设置了RPATH之后就不会有问题了。

编译安装工程

生成工程文件:

mkdir buildcd buildcmake ..

Windows上默认x86。如果要用x64,需要指定generator:

cmake -G"Visual Studio 14 2015 Win64" ..

编译安装:

cmake --build . --target install

在Linux上使用命令的时候前面要加上sudo

完整CMakeLists.txt

cmake_minimum_required (VERSION 2.6)project (BarcodeReader)MESSAGE( STATUS "PROJECT_NAME: " ${PROJECT_NAME} )# The version number.set(BarcodeReader_VERSION_MAJOR 1)set(BarcodeReader_VERSION_MINOR 0)# Check platformsif (CMAKE_HOST_WIN32)    set(WINDOWS 1)elseif(CMAKE_HOST_APPLE)    set(MACOS 1)elseif(CMAKE_HOST_UNIX)    set(LINUX 1)endif()# Set RPATHif(WINDOWS)else()    set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")    MESSAGE( STATUS "CMAKE_INSTALL_RPATH: " "${CMAKE_INSTALL_PREFIX}/lib" )    set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)endif()# Configure a header file to pass some of the CMake settings# to the source codeconfigure_file (    "${PROJECT_SOURCE_DIR}/BarcodeReaderConfig.h.in"    "${PROJECT_BINARY_DIR}/BarcodeReaderConfig.h")# Add search path for include and lib filesif(WINDOWS)    link_directories("${PROJECT_SOURCE_DIR}/platforms/win") elseif(LINUX)    link_directories("${PROJECT_SOURCE_DIR}/platforms/linux") elseif(MACOS)    link_directories("${PROJECT_SOURCE_DIR}/platforms/macos") endif()include_directories("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include")# Add the executableadd_executable(BarcodeReader BarcodeReader.cxx)if(WINDOWS)    if(CMAKE_CL_64)        target_link_libraries (BarcodeReader "DBRx64")    else()        target_link_libraries (BarcodeReader "DBRx86")    endif()else()    target_link_libraries (BarcodeReader "DynamsoftBarcodeReader")endif()if(WINDOWS)    # Copy DLL files to output directory    if(CMAKE_CL_64)        add_custom_command(TARGET BarcodeReader POST_BUILD         COMMAND ${CMAKE_COMMAND} -E copy_if_different        "${PROJECT_SOURCE_DIR}/platforms/win/DynamsoftBarcodeReaderx64.dll"                      $<TARGET_FILE_DIR:BarcodeReader>)    else()        add_custom_command(TARGET BarcodeReader POST_BUILD         COMMAND ${CMAKE_COMMAND} -E copy_if_different        "${PROJECT_SOURCE_DIR}/platforms/win/DynamsoftBarcodeReaderx86.dll"                      $<TARGET_FILE_DIR:BarcodeReader>)    endif()endif()# Set installation directoryif(WINDOWS)    set(CMAKE_INSTALL_PREFIX "e:/${PROJECT_NAME}")    if(CMAKE_CL_64)    install (FILES "${PROJECT_SOURCE_DIR}/platforms/win/DynamsoftBarcodeReaderx64.dll" DESTINATION bin)    else()    install (FILES "${PROJECT_SOURCE_DIR}/platforms/win/DynamsoftBarcodeReaderx86.dll" DESTINATION bin)    endif()elseif(LINUX)    install (FILES "${PROJECT_SOURCE_DIR}/platforms/linux/libDynamsoftBarcodeReader.so" DESTINATION lib)elseif(MACOS)    install (FILES "${PROJECT_SOURCE_DIR}/platforms/macos/libDynamsoftBarcodeReader.dylib" DESTINATION lib)endif()install (TARGETS BarcodeReader DESTINATION bin)install (FILES "${PROJECT_BINARY_DIR}/BarcodeReaderConfig.h" DESTINATION include)install (DIRECTORY "${PROJECT_SOURCE_DIR}/include" DESTINATION include)# Use CTestinclude(CTest)add_test (BarcodeReaderRuns BarcodeReader)

源码

https://github.com/dynamsoft-dbr/cmake

原创粉丝点击