使用CMake可以很方便的实现跨平台编译。如果要Link一个第三方库,需要针对平台进行设置。这里分享下如何创建一个简单的CMake工程实现Windows, Linux和macOS上的自动编译。
sudo apt-get install cmake
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 all
build 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
写了一个简单的命令行barcode reader。这里的重点是如何配置CMake,代码不解释。
可以浏览BarcodeReader.cxx
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()
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盘,如果命令行工具没有管理员权限会安装失败。所以可以更改默认安装路径。
# Set RPATH
if(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 build
cd build
cmake ..
Windows上默认x86。如果要用x64,需要指定generator:
cmake -G"Visual Studio 14 2015 Win64" ..
编译安装:
cmake --build . --target install
在Linux上使用命令的时候前面要加上sudo。
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 platforms
if (CMAKE_HOST_WIN32)
set(WINDOWS 1)
elseif(CMAKE_HOST_APPLE)
set(MACOS 1)
elseif(CMAKE_HOST_UNIX)
set(LINUX 1)
endif()
# Set RPATH
if(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 code
configure_file (
"${PROJECT_SOURCE_DIR}/BarcodeReaderConfig.h.in"
"${PROJECT_BINARY_DIR}/BarcodeReaderConfig.h"
)
# Add search path for include and lib files
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()
include_directories("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include")
# Add the executable
add_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"
$)
else()
add_custom_command(TARGET BarcodeReader POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${PROJECT_SOURCE_DIR}/platforms/win/DynamsoftBarcodeReaderx86.dll"
$)
endif()
endif()
# Set installation directory
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()
install (TARGETS BarcodeReader DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/BarcodeReaderConfig.h" DESTINATION include)
install (DIRECTORY "${PROJECT_SOURCE_DIR}/include" DESTINATION include)
# Use CTest
include(CTest)
add_test (BarcodeReaderRuns BarcodeReader)
https://github.com/dynamsoft-dbr/cmake