问题:最近在写一个工程的时候需要用到python3,但是由于引入了ROS相关的环境,导致希望使用python3的那部分代码一直默认使用ROS中的python2,这样环境就不对了。
解决的方法:很顺理成章的想法是为需要python3的那部分代码专门指定一个python3的环境,这需要在cmakelist中单独指出
方法
多目录CmakeLists.txt
大伙可能经常见到一些开源的工程中存在多个CmakeLists.txt,这么做的目的本质上是将代码分成好多块,每一块有一个单独CmakeLists.txt管理,最后只需一个总的CmakeLists.txt进行汇总即可。注意:此处掌管一块代码的CmakeLists.txt即可完成我们希望的功能。最简单的例子如下,我们有一个hello库+一个world库,他们俩又汇总成一个最终代码库,就有如下的工程目录结构:
而我们希望控制其中一个代码块的python版本并在主文件中调用这部分代码,我建议的代码格式为:
project_name/
——cmake
——sub_project_name.cmake
—— include
——src
——CmakeLists.txt(主)
——third_party
——sub_project_name
——include
——src
——CmakeLists.txt(子)
以上结构中,project_name为主文件夹,sub_project_name为我们希望控制python版本代码的代码块所在的子文件夹中,我们将他放在third_party中方便管理。接下来就要编写CmakeLists.txt了,关于其如何编写可以看看我之前的文章。
指定子库CmakeLists.txt中python版本
子库中的CmakeList.txt写法和正常情况基本相同,只不过将add_executable替换为了add_library,我们要在其中准确地指定python版本
cmake_minimum_required(VERSION 3.12.0)
project(CallAPI)
set( CMAKE_CXX_FLAGS "-std=c++14 -O3" )
SET(Python3_INCLUDE_DIRS "/usr/include/python3.6m")
SET(Python3_LIBRARIES "/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu/libpython3.6.so")
SET( PYTHON_EXECUTABLE /usr/bin/python3.6)
# find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
message("Python3: " ${Python3_INCLUDE_DIRS})
message("Python3: " ${Python3_LIBRARIES})
include_directories(./include/ ${Python3_INCLUDE_DIRS})
add_library(libCallAPI src/call_api.cpp)
target_link_libraries(libCallAPI ${Python3_LIBRARIES})
主CmakeLists.txt中连接子库
如我在之前的文章所讲,这边建议写一个sub_project_name.cmake文件来连接库,以我写的CallAPI库为例,.cmake内容如下
add_subdirectory(${PROJECT_SOURCE_DIR}/thirdparty/CallAPI)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/CallAPI/include/)
list(APPEND ALL_TARGET_LIBRARIES libCallAPI)
有了.cmake文件,在主CmakeLists.txt中只需要应用一下这个文件即可
...其他内容...
include(cmake/callapi.cmake)
...其他内容...
总结
如上,sub_project_name库的python版本就是你特定的那个版本,不会收到主或者其他CmakeLists.txt的影响啦。举一反三,当需要其他依赖的多版本环境时同样可以使用以上方法。