我有一个主要的c ++项目,我使用CMake来管理。设置cmake_install_prefix
和配置后,它将生成makefile,然后可以使用非常标准的makefile进行构建和安装:
make make install
至此,我的二进制文件最终以结束cmake_install_prefix
,而无需执行其他工作即可执行它们。最近,我在源代码树的几个位置添加了一些Python脚本,其中一些依赖于其他脚本。我可以使用CMake将Python文件和目录结构复制到cmake_install_prefix
,但是如果我进入该路径并尝试使用其中一个脚本,Python将找不到其他脚本,imports
因为PYTHONPATH
它不包含cmake_install_prefix
。我知道您可以使用CMake设置环境变量,但是它不会在各个shell之间持久存在,因此,对于用户而言,它不是真正的“设置”,而不仅仅是当前的终端会话。
解决方案似乎是在您的软件构建说明中增加一个步骤,说“设置您的PYTHONPATH”。有什么办法可以避免这种情况?这是作为较大项目的一部分“安装” Python脚本的标准做法吗?设置项目的持续集成似乎确实使事情复杂化,因为必须手动配置诸如Jenkins之类的东西才能注入环境变量,而构建和执行从c ++代码生成的可执行文件并不需要任何特殊的东西。
Python提供了sys.path
列表,该列表用于带有import
指令的搜索模块。您可以在添加模块之前调整此列表:
script1.py:
# Do some things useful for other scripts
script2.py.in:
# Uses script1.py. ... sys.path.insert(1, "@SCRIPT1_INSTALL_PATH@") import script1 ...
CMakeLists.txt:
... # Installation path for script1. Depends from CMAKE_INSTALL_PREFIX. set(SCRIPT1_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/<...>) install(FILES script1.py DESTINATION ${SCRIPT1_INSTALL_PATH} # Configure 'sys.path' in script2.py, so it may find script1.py. configure_file("script2.py.in" "script2.py" @ONLY) set(SCRIPT2_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/<...>) install(FILES script2.py DESTINATION ${SCRIPT2_INSTALL_PATH} ...
如果要让script2.py在构建树和安装树中都能工作,则需要有两个实例,一个在构建树中工作,另一个在安装后工作。可以从单个.in
文件配置两个实例。
如果是编译的可执行文件和库,则使用类似的机制来帮助二进制文件在非标准位置中查找库。它被称为RPATH。
因为CMake
知道创建的每个二进制文件(它跟踪add_executable
和 add_library
调用),
知道二进制文件之间的链接(target_link_libraries
也跟踪调用),
完全控制链接过程,
安装二进制文件时,CMake能够自动调整RPATH。
如果使用Python脚本,CMake没有此类信息,那么调整链接路径应手动执行。