尝试向输出 some/path/to/XXXX.rule 添加自定义规则,该规则在 windows 上的 qt5 cmake 中已有自定义规则

Attempt to add a custom rule to output some/path/to/XXXX.rule which already has a custom rule in qt5 cmake on windows

我正在将我的代码移植到构建的 windows 和 Ubuntu 上的 运行(在 qt 5.15.1 中使用 cmake)。在我的项目中,我想将我的主要源文件构建到库中,然后 link 将其构建为可执行文件(当我们在大型项目中合作时有意义)。

环境:

Windows10 64bits
Visual Studio 2019
Cmake 3.18.1
Qt 5.15.1

但是 cmake 报错了一些错误:

Running D:\Qt\Tools\CMake_64\bin\cmake.exe -S E:/test/test -B E:/test/build-test-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug in E:\test\build-test-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug.
-- Configuring done
-- Generating done
-- Build files have been written to: E:/test/build-test-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug
Elapsed time: 00:00.
Running D:\Qt\Tools\CMake_64\bin\cmake.exe -S E:/test/test -B E:/test/build-test-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug in E:\test\build-test-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug.
-- Configuring done
CMake Error in CMakeLists.txt:
  Attempt to add a custom rule to output

    E:/test/build-test-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug/test_autogen/timestamp.rule

  which already has a custom rule.


CMake Error in CMakeLists.txt:
  Cannot find source file:

    E:/test/build-test-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug/CMakeFiles/test_autogen_timestamp_deps

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .m .M .mm .h .hh .h++ .hm
  .hpp .hxx .in .txx


CMake Error in CMakeLists.txt:
  Cannot find source file:

    E:/test/build-test-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug/CMakeFiles/test_autogen

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .m .M .mm .h .hh .h++ .hm
  .hpp .hxx .in .txx


CMake Error: The inter-target dependency graph contains the following strongly connected component (cycle):
  "test" of type STATIC_LIBRARY
    depends on "Test_autogen_timestamp_deps" (strong)
    depends on "Test_autogen" (strong)
  "Test_autogen_timestamp_deps" of type UTILITY
    depends on "test" (strong)
  "Test_autogen" of type UTILITY
    depends on "Test_autogen_timestamp_deps" (strong)
At least one of these targets is not a STATIC_LIBRARY.  Cyclic dependencies are allowed only among static libraries.
CMake Generate step failed.  Build files cannot be regenerated correctly.
CMake process exited with exit code 1.
Elapsed time: 00:00.

这里我注意到 timestamp 和一个 cycle link 问题,但它们不是我自己创建或需要的(也许它们是由 qt 自动生成的?)。

要重现该问题,您只需使用 QtCreator 创建一个最小的默认桌面应用程序,名为 Test,由 cmake 构建。并使用以下 CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)

project( Test LANGUAGES CXX)
set( TEST_SDK test)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED)

include_directories( ${Qt5Widgets_INCLUDE_DIRS} )

add_library(${TEST_SDK} mainwindow.cpp mainwindow.h mainwindow.ui)
target_link_libraries(${TEST_SDK} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

add_executable( ${PROJECT_NAME} main.cpp)
target_link_libraries( ${PROJECT_NAME} ${TEST_SDK})

到目前为止,运行 Cmake 在 QtCreator 中,这些错误会出现。总结起来主要有两个错误:

Attempt to add a custom rule to output

    E:/test/build-test-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug/test_autogen/timestamp.rule

  which already has a custom rule.

At least one of these targets is not a STATIC_LIBRARY.  Cyclic dependencies are allowed only among static libraries.

...

CMake Error: The inter-target dependency graph contains the following strongly connected component (cycle):

...

好吧,最后,我用一个非常偶然的方式解决了这个问题。而且我认为我最初的问题在某种程度上不适合我的真实问题,所以我会更新我的问题和相关内容。

这个问题背后的原因是可执行文件和库的名称相同(在这个被质疑的案例中)。要使其通过 cmake 构建过程,只需将 TEST_SDK 名称更改为任何其他名称(只要它与该可执行文件名称不同),例如从 test 更改为 test_sdk :

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project( Test LANGUAGES CXX)
set( TEST_SDK test_sdk)       # we only need to change this line

...

我没有深入研究原因,但我认为这里的两个名称(这里是 Test 可执行文件和 test 库)在 windows 上是相同的吗?

在我的例子中,我有两个 add_custom_command 调用相同的 OUTPUT 文件,
但是 add_custom_command 调用在两个不同的 CMakeLists.txt 文件中

cmake 应该打印更好的错误消息,例如
OUTPUT path/to/file is already produced
by add_custom_command in path/to/CMakeLists.txt line x