You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何配置CMake在构建前自动运行Python脚本,适配源文件及脚本变更?

How to Automatically Run a Python Script Before C++ Builds (With Change Detection)

Great question! Setting up CMake to run your genenums.py script automatically—especially with proper dependency tracking—is straightforward once you know the right commands. Let's break this down into your specific use case first, then cover the general approach for any Python build script.

Specific Solution for genenums.py

Here's how to configure CMake to run your script before building, and trigger reruns whenever your C++ source files or the script itself change:

Step 1: Track Input Dependencies

First, we need to tell CMake which files should trigger a rerun of genenums.py. That includes:

  • The script itself (genenums.py)
  • All your C++ source files (.h, .cpp) in the project directory

You can collect the C++ files using file(GLOB_RECURSE) (note: if your project has a stable set of files, listing them explicitly is more reliable than GLOB, but GLOB works for dynamic cases):

# Collect all C++ source files (adjust paths as needed)
file(GLOB_RECURSE CPP_SOURCES
    ${PROJECT_SOURCE_DIR}/src/*.h
    ${PROJECT_SOURCE_DIR}/src/*.cpp
)

# The script itself is a critical dependency
set(GEN_ENUMS_SCRIPT ${PROJECT_SOURCE_DIR}/genenums.py)

Step 2: Define Output Files

Next, specify the exact files that genenums.py generates. Replace these with your actual output file paths:

# Example output files (adjust to match your script's actual output)
set(GEN_ENUMS_OUTPUTS
    ${PROJECT_BINARY_DIR}/generated_enums.h
    ${PROJECT_BINARY_DIR}/generated_enums.cpp
)

Step 3: Add a Custom Command to Run the Script

Use add_custom_command to define how to generate the output files. This command will only run if the inputs or script have changed:

add_custom_command(
    OUTPUT ${GEN_ENUMS_OUTPUTS}
    COMMAND python3 ${GEN_ENUMS_SCRIPT}  # Use "python" instead of "python3" if needed on your system
    DEPENDS ${GEN_ENUMS_SCRIPT} ${CPP_SOURCES}
    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}  # Ensure script runs in your project root
    COMMENT "Generating enum definitions with genenums.py..."
)

Step 4: Create a Custom Target

We need a target to tie the custom command to, so CMake knows to run it before building your main project:

add_custom_target(GenerateEnums ALL
    DEPENDS ${GEN_ENUMS_OUTPUTS}
)

The ALL keyword ensures this target is built by default when you run make or cmake --build.

Step 5: Make Your Main Project Depend on This Target

Finally, link your main executable/library target to the GenerateEnums target so it runs first:

# Assume your main target is called "MyProject"
add_executable(MyProject main.cpp ...)  # Your existing target definition
add_dependencies(MyProject GenerateEnums)

# Don't forget to include the generated files' directory in your include paths
target_include_directories(MyProject PRIVATE ${PROJECT_BINARY_DIR})

General Method for Running Python Scripts in CMake

The pattern above applies to any Python script that generates build-time files. Here's the general workflow:

  1. Identify Inputs: List all files the script depends on (the script itself, source files, config files, etc.)
  2. Specify Outputs: Define the exact files the script produces—CMake uses these timestamps to check if a rerun is needed.
  3. Custom Command: Use add_custom_command to map inputs to outputs via the Python execution command.
  4. Custom Target: Wrap the custom command in add_custom_target to integrate it into the build pipeline.
  5. Link to Main Target: Use add_dependencies to ensure your main project waits for the script to finish before building.

Key Notes

  • Dependency Tracking: CMake automatically checks modification timestamps of inputs and outputs. If any input is newer than the outputs, the script runs again.
  • Python Path: Use python or python3 depending on your system's setup. If Python is in a non-standard location, specify the full path (e.g., /usr/local/bin/python3).
  • Working Directory: The WORKING_DIRECTORY parameter ensures the script runs in the correct folder to find source files or write outputs to the right place.
  • Explicit vs. GLOB: While GLOB_RECURSE is convenient, explicitly listing source files avoids missing new files added after the initial CMake run. For projects with frequent file additions, consider rerunning CMake when new files are added.

That's it! This setup will ensure your genenums.py runs automatically whenever needed, and integrates seamlessly with your CMake build process.

内容的提问来源于stack exchange,提问作者irfna

火山引擎 最新活动