You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake跨目标循环依赖问题:如何避免多次运行CMake编译?

This is a classic CMake dependency ordering issue—here's what's happening and how to fix it:

When CMake runs the first time, it processes add_subdirectory(foo) first. At that point, the bar target hasn't been defined yet (since add_subdirectory(bar) comes later). So when foo's CMakeLists tries to create a test executable that links against bar, CMake can't resolve that target immediately. On the second run, since bar exists in the cache, it fills in the missing dependency and everything works.

The cleanest fixes avoid this "chicken-and-egg" scenario entirely. Here are two practical approaches:

1. Move cross-dependent tests to a parent directory

Since your foo tests need bar's functionality, move them out of the foo subdirectory and define them in the libs/CMakeLists.txt after both foo and bar are added. This ensures both targets exist when the test is created:

# libs/CMakeLists.txt
add_subdirectory(foo)  # Process foo first (bar depends on it)
add_subdirectory(bar)  # Now bar is fully defined

# Add foo's tests that depend on bar
add_executable(foo_feature_test
    foo/test/new_feature_tests.cpp  # Path to your test files
)
target_link_libraries(foo_feature_test
    PRIVATE
        foo  # Link against foo's library
        bar  # Link against bar's library (now exists!)
)

# Register the test with CTest
add_test(NAME FooNewFeatures COMMAND foo_feature_test)

Then, remove the test-related code from foo/CMakeLists.txt. This way, CMake resolves all dependencies in a single run.

2. Refactor to eliminate cross-test dependencies (if possible)

If moving tests feels messy, see if you can extract the bar functionality needed by foo's tests into a small, shared utility library that both foo and bar depend on. For example:

  • Create a libs/util subdirectory with its own CMakeLists.txt
  • Move the shared code into util
  • Update foo and bar to link against util
  • Now foo's tests can link against foo and util instead of bar, avoiding the need to wait for bar to be processed.

Why this works

CMake processes add_subdirectory calls sequentially, so targets defined in later subdirectories aren't available to earlier ones. By defining the cross-dependent test after both libraries are set up, you avoid the "target not found" state that triggers the need for a second CMake run.

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:28:19