Linux CMake根据环境变量和编译选项,编译多模块
CMakeLists.txt文件如下(例):
# 编译选项决定了单次编译某一个或某一些模块
#
#
# 仅编译模块1:
# cmake . -D 编译选项1=ON && make install
# cmake后跟的一个小点"."(即"./"),指向CMakeLists.txt脚本所在的目录
#
#
# 若模块1编译失败了,此时希望仅编译模块2:
# cmake . -D 编译选项2=ON -D 编译选项1=OFF && make install
# 如果模块1编译失败,此后编译其他模块前需要清除模块1的编译选项
# 清除编译错误的模块1,也可以通过删除编译中间文件目录解决:
# rm CMakeCache.txt && rm -rf CMakeFiles/
# 此后编译模块2可以不指定"-D 编译选项1=OFF",如:cmake . -D 编译选项2=ON && make install
# 总结:"-D 编译选项1=OFF" 或 删除编译中间文件目录 都能清除上一次编译失败的模块1的影响
#
#
# ALL选项会启用所有编译选项,在使用ALL=ON时,设置的其他编译选项=OFF会失效
# 如:-D ALL=ON -D COMCALSRV=OFF
# 此时COMCALSRV=OFF选项会失效,其已被ALL=ON设置为ON
# 可以按照需要,将ALL类比到SCADA、NEWFERT、GRAPH等
#
#
# 本脚本仅按照环境变量FWPATH、FWSRCPATH,寻找编译源码、链接库、输出文件安装路径
# 即,本脚本可以在任意目录执行构建行为
# 由于编译输出文件可能较多,也可能会因为编译失败,需要清除已有的全部编译输出文件目录
# 建议在脚本所在目录创建编译输出目录:mkdir out
# 后续编译行为都在这个out目录进行:cd out
# 构建命令中,CMakeLists.txt脚本文件所在目录也从当前目录(./)变为上一级目录(../),如:
# cmake .. -D 编译选项=ON && make install
cmake_minimum_required(VERSION 3.10)
# 设置版本号
set(VERSION_MAJOR 1)
set(VERSION_MINOR 0)
set(VERSION_PATCH 0)
# 忽略编译警告
add_definitions(-w)
# 设置编译选项,下列选项在值为ON时,对应模块才会被编译
option(ALL "Enable building all modules" OFF)
option(COMCALSRV "Enable building comcalsrv" OFF)
option(PROT102 "Enable building prot102" OFF)
option(PROT104 "Enable building prot104" OFF)
option(PROT809 "Enable building prot809" OFF)
# 指定编译架构:32位(需要编译64位则把m32换成m64即可)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
# 获取环境变量
set(FWPATH "$ENV{FWPATH}")
set(FWSRCPATH "$ENV{FWSRCPATH}")
# 检查环境变量是否被设置
if(NOT FWPATH)
message(FATAL_ERROR "Environment variable FWPATH is not set.")
endif()
if(NOT FWSRCPATH)
message(FATAL_ERROR "Environment variable FWSRCPATH is not set.")
endif()
# ########################################################################################
# ########################################################################################
# 以下是每个模块的编译函数,直至第 200 行左右
# ########################################################################################
# ########################################################################################
# comcalsrv 模块的构建函数
function(compile_comcalsrv)
# 设置C++标准(注意:CMake 2.8.6不支持直接设置C++标准,但可以通过编译器标志来设置)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 指定头文件目录
include_directories(
${FWSRCPATH}/inc
${FWSRCPATH}/include
${FWSRCPATH}/program/app/newfert/include
${FWSRCPATH}/program/app/newfert/source
)
# 指定编译输出文件与源文件列表
add_executable(comcalsrv
${FWSRCPATH}/program/app/newfert/source/comcalsrvmain.cxx
${FWSRCPATH}/program/app/newfert/source/comuserlogic.cxx
)
# 指定链接库目录
link_directories(
${FWPATH}/lib
${FWPATH}/lib/protocol
${FWPATH}/lib/protect
)
# 指定链接库列表
target_link_libraries(comcalsrv
libpscsl.so
libpsmsl.so
libcomci.so
libpsalarm.so
libscadaci.so
libmulcommod.so
libnetdata.so
libgrpdre.so
libbaseprot.so
libcomdev.so
libpthread.so
libexpce.so
libupl.so
librtdb.so
libdbci.so
libpspython.so
)
# 编译成功后,将输出文件安装到指定位置
install(TARGETS comcalsrv
RUNTIME DESTINATION ${FWPATH}/bin # 可执行文件的安装路径
LIBRARY DESTINATION ${FWPATH}/lib/protocol # 动态库文件的安装路径
ARCHIVE DESTINATION ${FWPATH}/lib/protocol # 静态库文件的安装路径
)
endfunction()
# libprot102 模块的构建函数
function(compile_prot102)
# 指定头文件目录
include_directories(
${FWSRCPATH}/inc
${FWSRCPATH}/include
${FWSRCPATH}/program/app/newfert/include
${FWSRCPATH}/program/app/newfert/source
${FWSRCPATH}/program/app/newfert/protocol/include
${FWSRCPATH}/program/app/newfert/protocol/source
)
# 指定链接库目录
link_directories(
${FWPATH}/lib
${FWPATH}/lib/protocol
)
# 指定编译输出文件与源文件列表
add_library(prot101 SHARED
${FWSRCPATH}/program/app/newfert/protocol/source/iec101-v2002.cxx
)
# 指定链接库列表
target_link_libraries(prot101
libbaseprot.so
librtdb.so
libpsmsl.so
libpscsl.so
)
# 编译成功后,将输出文件安装到指定位置
install(TARGETS prot101
RUNTIME DESTINATION ${FWPATH}/bin # 可执行文件的安装路径
LIBRARY DESTINATION ${FWPATH}/lib/protocol # 动态库文件的安装路径
ARCHIVE DESTINATION ${FWPATH}/lib/protocol # 静态库文件的安装路径
)
endfunction()
# libprot104 模块的构建函数
function(compile_prot104)
# 指定头文件目录
include_directories(
${FWSRCPATH}/inc
${FWSRCPATH}/include
${FWSRCPATH}/program/app/newfert/include
${FWSRCPATH}/program/app/newfert/source
${FWSRCPATH}/program/app/newfert/protocol/include
${FWSRCPATH}/program/app/newfert/protocol/source
)
# 指定链接库目录
link_directories(
${FWPATH}/lib
${FWPATH}/lib/protocol
)
# 指定编译输出文件与源文件列表
add_library(prot104 SHARED
${FWSRCPATH}/program/app/newfert/protocol/source/iec104_d.cxx
)
# 指定链接库列表
target_link_libraries(prot104
libbaseprot.so
librtdb.so
libpsmsl.so
libpscsl.so
)
# 编译成功后,将输出文件安装到指定位置
install(TARGETS prot104
RUNTIME DESTINATION ${FWPATH}/bin # 可执行文件的安装路径
LIBRARY DESTINATION ${FWPATH}/lib/protocol # 动态库文件的安装路径
ARCHIVE DESTINATION ${FWPATH}/lib/protocol # 静态库文件的安装路径
)
endfunction()
# libprot809 模块的构建函数
function(compile_prot809)
# 指定头文件目录
include_directories(
${FWSRCPATH}/inc
${FWSRCPATH}/include
${FWSRCPATH}/program/app/newfert/include
${FWSRCPATH}/program/app/newfert/source
${FWSRCPATH}/program/app/newfert/protocol/include
${FWSRCPATH}/program/app/newfert/protocol/source
)
# 指定链接库目录
link_directories(
${FWPATH}/lib
${FWPATH}/lib/protocol
)
# 指定编译输出文件与源文件列表
add_library(prot809 SHARED
${FWSRCPATH}/program/app/newfert/protocol/source/protocol_ModbusTCP_HVAC.cxx
)
# 指定链接库列表
target_link_libraries(prot809
libbaseprot.so
librtdb.so
libpsmsl.so
libpscsl.so
)
# 编译成功后,将输出文件安装到指定位置
install(TARGETS prot809
RUNTIME DESTINATION ${FWPATH}/bin # 可执行文件的安装路径
LIBRARY DESTINATION ${FWPATH}/lib/protocol # 动态库文件的安装路径
ARCHIVE DESTINATION ${FWPATH}/lib/protocol # 静态库文件的安装路径
)
endfunction()
# ########################################################################################
# ########################################################################################
# 结束对每个模块的编译函数的声明与定义
# ########################################################################################
# ########################################################################################
# 检查是否启用了ALL选项,如果是,则编译所有模块
if(ALL)
set(COMCALSRV ON)
set(PROT102 ON)
set(PROT104 ON)
set(PROT809 ON)
endif()
if(COMCALSRV)
compile_comcalsrv()
endif()
if(PROT809)
compile_prot809()
endif()
if(PROT102)
compile_prot102()
endif()
if(PROT104)
compile_prot104()
endif()
执行示例图: