【问题标题】:CMake out of source build - Python filesCMake out of source build - Python 文件
【发布时间】:2012-12-07 05:18:41
【问题描述】:

我使用 CMake 为我的项目创建构建脚本(Makefiles + VS 解决方案)。作为最佳实践,我在单独的文件夹中创建构建脚本(源代码外)。我在同一个文件夹中构建项目。

这适用于已编译的程序,但我无法为我的 Python 脚本找到合适的解决方案,因为这些脚本没有将它们复制 (build) 到构建文件夹的构建步骤。

寻找创造性的解决方案....

要求:

  • 所有可执行文件都应该在构建后的构建文件夹中可用(我认为 *.py 文件是可执行文件
  • 应该使用 IDE(spyder、eclipse 等)轻松管理 Python 脚本
  • 包含 python 脚本的源文件夹位于 Git 存储库中。构建文件夹不是。
  • C++ 编译的 Python 模块应该位于相关的 Python 脚本旁边

到目前为止,我考虑了两种选择:

  • 在运行 CMake 时将脚本复制到构建文件夹 - 需要为 python 文件中的每个更改运行 CMake(IDE 不友好)。可能会引起混淆:要编辑哪个来源的副本?
  • 在构建文件夹中创建指向源文件夹的链接 - 多平台混乱。在脚本旁边部署已编译的 c++ python 模块而不污染源文件夹时出现问题。

我希望这已经足够清楚了。

【问题讨论】:

    标签: python makefile cmake


    【解决方案1】:

    最终我找到了一个解决方案,它涉及创建指向 python 源代码和其他相关文件的符号链接,这些文件未编译但在构建环境中是必需的。为了允许将构建的模块与符号链接混合,我使用了真正的文件夹而不是符号链接。

    这边:

    • python 脚本只有一份
    • 可以从二进制文件夹无缝运行/编辑

    实用功能:

    function (create_symlinks)
        # Do nothing if building in-source
        if (${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
            return()
        endif()
    
        foreach (path_file ${ARGN})
            get_filename_component(folder ${path_file} PATH)
    
            # Create REAL folder
            file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${folder}")
    
            # Delete symlink if it exists
            file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/${path_file}")
    
            # Get OS dependent path to use in `execute_process`
            file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${path_file}" link)
            file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${path_file}" target)
    
            if (UNIX)
                set(command ln -s ${target} ${link})
            else()
                set(command cmd.exe /c mklink ${link} ${target})
            endif()
    
            execute_process(COMMAND ${command} 
                            RESULT_VARIABLE result
                            ERROR_VARIABLE output)
    
            if (NOT ${result} EQUAL 0)
                message(FATAL_ERROR "Could not create symbolic link for: ${target} --> ${output}")
            endif()
    
        endforeach(path_file)
    endfunction(create_symlinks)
    

    python 模块的用法(在 CMakeLists.txt 中):

    # Do not omit !!!RELATIVE!!!
    file(GLOB_RECURSE files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.py *.dat *.xml)
    create_symlinks(${files})
    

    用法:

    cd src_dir
    mkdir build_dir
    cd build_dir
    cmake ..
    

    重要提示:

    • 添加新文件时不要忘记运行cmake
    • 在 Windows 上 mklink 仅支持 some Windows versions
    • 在 Windows 上 mklink 只能以管理员身份运行。可以找到解决方法here
    • 调用create_symlinks 时使用相对路径,因为这是在二进制文件夹中重建目录结构的方式。

    【讨论】:

    • 请注意,仅适用于不包含空格的文件名
    【解决方案2】:

    我将通过创建自定义命令将 python 脚本编译到构建文件夹中,如this post 所示。

    【讨论】:

    • 但是谁负责构建 python 目标呢? VS 解决方案?生成文件?每次 python 源更改时运行 3rd 方构建脚本真的很奇怪。
    猜你喜欢
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    • 2023-04-01
    • 2020-04-09
    • 2019-08-28
    • 2013-04-27
    • 2018-08-01
    • 2016-04-23
    相关资源
    最近更新 更多