Pylon5 自带的例子使用 Makefile
。但是,CLion 默认建立的项目是 CMake
的。为了能在 CLion 下写代码,我们必须将原有的 Makefile 转成 CMakeList。
但是,Google 告诉我,并没有工具能自动完成这件事…… 那好,一点一点自己来吧。
我们以 Pylon5 自带例子中 C++/Grab
为例,将 Makefile“翻译”成 CMakeLists.txt。
原有的 Makefile
# Makefile for Basler pylon sample program
.PHONY: all clean
# The program to build
NAME := Grab
# Installation directories for pylon
PYLON_ROOT ?= /opt/pylon5
# Build tools and flags
LD := $(CXX)
CPPFLAGS := $(shell $(PYLON_ROOT)/bin/pylon-config --cflags)
CXXFLAGS := #e.g., CXXFLAGS=-g -O0 for debugging
LDFLAGS := $(shell $(PYLON_ROOT)/bin/pylon-config --libs-rpath)
LDLIBS := $(shell $(PYLON_ROOT)/bin/pylon-config --libs)
# Rules for building
all: $(NAME)
$(NAME): $(NAME).o
$(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
$(NAME).o: $(NAME).cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
clean:
$(RM) $(NAME).o $(NAME)
翻译
前几行看起来无关紧要。那么就从 PYLON_ROOT ?= /opt/pylon5
这一行开始。看起来像是个赋值语句,并且下面也用到了 $(PYLON_ROOT)
这样的写法。那么,我们把这句话翻译成 set(PYLON_ROOT "/opt/pylon5")
。
下面,LD:= $(CXX)
。直接在 shell 里面输入 echo $(CXX)
并没有什么东西,就直接忽略了。感觉这句话只是 “取个别名” 而已。
再下面,重点来了。CPPFLAGS := $(shell $(PYLON_ROOT)/bin/pylon-config --cflags)
这句话,明显的是执行一个 shell 语句,获得执行结果,再赋值。Google 了好久,最终得到以下结果:
EXEC_PROGRAM("${PYLON_ROOT}/bin/pylon-config" ARGS --cflags OUTPUT_VARIABLE CPPFLAGS)
SET(CPPFLAGS "${CPPFLAGS}" CACHE STRING "CPPFLAGS")
而且,Makefile 里面的 CPPFLAGS
好像是对应 CMakeLists 里面的 CMAKE_C_FLAGS
的。那么,下面再加一句
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CPPFLAGS}")
这里就会有人问了,下面这样写,不行么?
EXEC_PROGRAM("${PYLON_ROOT}/bin/pylon-config" ARGS --cflags OUTPUT_VARIABLE CPPFLAGS)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CPPFLAGS}" CACHE STRING "CPPFLAGS")
还真不行。原因未知。
如法炮制余下的 LDFLAGS
和 LDLIBS
。LDFLAGS
对应的是 CMAKE_EXE_LINKER_FLAGS
,LDLIBS
需要写在 target_link_libraries
里。
结果
cmake_minimum_required(VERSION 3.6)
project(camera)
find_package(OpenCV REQUIRED)
set(PYLON_ROOT "/opt/pylon5")
include_directories("${PROJECT_BINARY_DIR}")
include_directories("${PYLON_ROOT}/include")
EXEC_PROGRAM("${PYLON_ROOT}/bin/pylon-config" ARGS --cflags OUTPUT_VARIABLE CPPFLAGS)
#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CPPFLAGS}" CACHE STRING "CPPFLAGS")
SET(CPPFLAGS "${CPPFLAGS}" CACHE STRING "CPPFLAGS")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CPPFLAGS}")
EXEC_PROGRAM("${PYLON_ROOT}/bin/pylon-config" ARGS --libs-rpath OUTPUT_VARIABLE LDFLAGS)
#SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LDFLAGS}" CACHE STRING "LDFLAGS")
SET(LDFLAGS "${LDFLAGS}" CACHE STRING "LDFLAGS")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LDFLAGS}")
EXEC_PROGRAM("${PYLON_ROOT}/bin/pylon-config" ARGS --libs OUTPUT_VARIABLE LDLIBS)
SET(LDLIBS "${LDLIBS}" CACHE STRING "LDLIBS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
set(SOURCE_FILES main.cpp)
add_executable(camera ${SOURCE_FILES})
target_link_libraries(camera ${OpenCV_LIBS} ${LDLIBS})
结束
把 Grab.cpp
一字不差抄过来,编译,成功。
转译得好像不是特别简洁,但是能用。这就行了。
至于为什么参数是 -std=c++14
…… 因为 Bjarne Stroustrup 老爷子昨天来学校演讲说,要用新标准,要用新标准……“你一个字都不用改动,使用新标准进行编译,就能获得巨大的性能提升”。就相信你一次喽~
发表回复