MacOS 上的 CTest 错误:未找到测试可执行文件

7 c++ continuous-integration cmake ctest azure-pipelines

我正在做一个 CMake 项目。对于 CI,我决定使用 Azure Pipelines。但是,我在测试阶段在 MacOS 上遇到了一个小问题。问题是 MacOS 无法找到测试可执行文件,即使它在那里。

早些时候,我的项目没有正确构建。但是现在整个管道运行成功(感谢 Stack Overflow 社区),除了 MacOS 上的小故障。我已经更新了我的问题,现在它说明了问题是什么以及我如何修复它,以便它可能对像我这样的 CI 世界的新手有所帮助。

编辑1

早些时候我的 CMake 任务没有触发构建过程。这是因为我没有为 CMake 提供任何命令行参数。我所做的就是这样:

- task: CMake@1
  displayName: Generate CMake Cache
  inputs:
    workingDirectory: build
Run Code Online (Sandbox Code Playgroud)

我认为 CMake 任务会自动驱动构建过程,因为文档中没有明确指定该任务实际执行的操作。除了打印 CMake 用法之外,这没有任何作用。然后我发现我们必须使用适当的命令行参数运行 CMake 任务两次(一次用于项目配置,然后用于实际构建)。

编辑2

这是我更新的 AzurePipelines.yml 文件

Azure 管道 CI

stages:
- stage: Build
  displayName: Build

  jobs:
  - job: RunCMakeTask
    displayName: Run CMake Task

    strategy:
      matrix:
        LinuxDebug:
          OS: 'Linux'
          imageName: 'ubuntu-latest'
          BuildConfiguration: 'Debug'
        LinuxRelease:
          OS: 'Linux'
          imageName: 'ubuntu-latest'
          BuildConfiguration: 'RelWithDebInfo'
        MacOSDebug:
          OS: 'MacOS'
          imageName: 'macos-latest'
          BuildConfiguration: 'Debug'
        MacOSRelease:
          OS: 'MacOS'
          imageName: 'macos-latest'
          BuildConfiguration: 'RelWithDebInfo'
        WindowsDebug:
          OS: 'Windows'
          imageName: 'windows-latest'
          BuildConfiguration: 'Debug'
        WindowsRelease:
          OS: 'Windows'
          imageName: 'windows-latest'
          BuildConfiguration: 'RelWithDebInfo'

    pool:
      vmImage: $(imageName)

    steps:
    - script: mkdir $(BuildConfiguration)
      displayName: Create Build Directory
      workingDirectory: $(Build.SourcesDirectory)
    - task: CMake@1
      displayName: Generate CMake Cache
      inputs:
        workingDirectory: $(BuildConfiguration)
        cmakeArgs: '-DCMAKE_BUILD_TYPE=$(BuildConfiguration) ..'
    - task: CMake@1
      displayName: Run Build Process
      inputs:
        workingDirectory: $(BuildConfiguration)
        cmakeArgs: '--build . --config $(BuildConfiguration)'
    - task: PublishPipelineArtifact@1
      displayName: Publish Build Artifact
      inputs:
        targetPath: $(BuildConfiguration)
        artifactName: '$(OS)$(BuildConfiguration)'
    
- stage: Test   
  displayName: Test
  dependsOn: Build

  jobs:
  - job: RunCTestOnWindows
    displayName: Run CTest on Windows

    variables:
      OS: Windows

    strategy:
      matrix:
        Debug:
          BuildConfiguration: 'Debug'
        Release:
          BuildConfiguration: 'RelWithDebInfo'

    pool:
      vmImage: 'windows-latest'

    steps:
    - task: DownloadPipelineArtifact@2
      displayName: Download Build Artifact
      inputs:
        artifact: '$(OS)$(BuildConfiguration)'
        path: $(Build.SourcesDirectory)/$(BuildConfiguration)
    - script: ctest -C $(BuildConfiguration) --output-on-failure
      workingDirectory: $(BuildConfiguration)
      
  - job: RunCTestOnUnixBasedSystems
    displayName: Run CTest on Unix Based Systems

    strategy:
      matrix:
        LinuxDebug:
          OS: 'Linux'
          imageName: 'ubuntu-latest'
          BuildConfiguration: 'Debug'
        LinuxRelease:
          OS: 'Linux'
          imageName: 'ubuntu-latest'
          BuildConfiguration: 'RelWithDebInfo'
        MacOSDebug:
          OS: 'MacOS'
          imageName: 'macos-latest'
          BuildConfiguration: 'Debug'
        MacOSRelease:
          OS: 'MacOS'
          imageName: 'macos-latest'
          BuildConfiguration: 'RelWithDebInfo'

    steps:
    - task: DownloadPipelineArtifact@2
      displayName: Download Build Artifact
      inputs:
        artifact: '$(OS)$(BuildConfiguration)'
        path: $(Build.SourcesDirectory)/$(BuildConfiguration)
    - script: find $(BuildConfiguration)/Tests -type f -name "Test*" ! -name "*.*" ! -exec chmod u+rx {} \;
      displayName: Change File Permissions
    - script: ctest -C $(BuildConfiguration) --output-on-failure
      workingDirectory: $(BuildConfiguration)
Run Code Online (Sandbox Code Playgroud)

管道在 Windows 和 Linux 上运行良好,但我在 MacOS 上遇到了一个小问题。在 MacOS 上,ctest即使存在测试可执行文件,也无法找到它。(如果我的管道或我的 CMakeLists.txt 文件中有任何问题,它也应该在 Windows 和 Linux 上失败)

编辑3

在 MacOS 的测试阶段,我收到错误消息:

测试项目/home/vsts/work/1/s/Debug Start 1: StringOperations_CaseIgnore Could not find executable /Users/runner/work/1/s/Debug/Tests/StringOperations/TestStringOperations 在以下地方看了下:/Users/runner/work/1/s/Debug/Tests/StringOperations/TestStringOperations /Users/runner/work/1/s/Debug/Tests/StringOperations/TestStringOperations /Users/runner/work/1/s/Debug/Tests /StringOperations/Debug/TestStringOperations /Users/runner/work/1/s/Debug/Tests/StringOperations/Debug/TestStringOperations Debug//Users/runner/work/1/s/Debug/Tests/StringOperations/TestStringOperations Debug//Users /runner/work/1/s/Debug/Tests/StringOperations/TestStringOperations Users/runner/work/1/s/Debug/Tests/StringOperations/TestStringOperations Users/runner/work/1/s/Debug/Tests/StringOperations/TestStringOperations Users/runner/work/1/s/Debug/Tests/StringOperations/Debug/TestStringOperations Users/runner/work/1/s/Debug/Tests/StringOperations/Debug/TestStringOperations Debug/Users/runner/work/1/s/调试/测试/字符串操作/测试字符串操作调试/用户/运行器/work/1/s/Debug/Tests/StringOperations/TestStringOperations 1/1 测试 #1:StringOperations_CaseIgnore ......***未运行 0.00 秒

0% 测试通过,1 次测试失败,1 次测试失败

总测试时间(实际)= 0.00 秒

以下测试失败:1 - StringOperations_CaseIgnore(未运行)无法找到可执行文件:/Users/runner/work/1/s/Debug/Tests/StringOperations/TestStringOperations 运行 CTest 时出错

编辑4

我尝试使用以下方法检查测试可执行文件是否实际存在:

ls -l Debug/Tests/StringOperations
Run Code Online (Sandbox Code Playgroud)

这是输出:

drwxr-xr-x 3 vsts docker    4096 Aug  6 15:05 CMakeFiles
-rw-r--r-- 1 vsts docker    1208 Aug  6 15:05 cmake_install.cmake
-rw-r--r-- 1 vsts docker     642 Aug  6 15:05 CTestTestfile.cmake
-rw-r--r-- 1 vsts docker    9838 Aug  6 15:05 Makefile
-rwxr--r-- 1 vsts docker 1715072 Aug  6 15:05 TestStringOperations
Run Code Online (Sandbox Code Playgroud)

这证实了测试可执行文件 (TestStringOperations) 与用于 Windows 和 Linux 的位置相同,但该过程仍然失败。

如果您需要,这里是此可执行文件的 CMakeLists.txt:

Set(SRC StringOperations.cpp)

Add_Executable(TestStringOperations ${SRC})

Target_Include_Directories(TestStringOperations PUBLIC
                           ${HEADER_PATH}/StringOperations
)

Target_Link_Libraries(TestStringOperations
                      PRIVATE ${GTEST_LIBS}
                      PRIVATE StringOperations
)

Add_Test(NAME StringOperations_CaseIgnore COMMAND TestStringOperations)
Run Code Online (Sandbox Code Playgroud)

我曾尝试在 Stack Overflow 和其他一些网站上寻求有关此问题的帮助,但他们的解决方案并没有使我受益。

例如: CTest 找不到可执行文件CMake:如何指定 ctest查找可执行文件的目录?

如果您需要更多信息,是我在 GitHub 上的项目。您还可以参考dev.azure.com上的管道日志。

你能帮我解决这个问题吗?也欢迎有关此文件的整体实施的任何建议。

Dre*_*ost 3

尝试在构建后运行发布管道工件任务。正如评论中所回避的那样,这将发布您的构建内容并允许其跨阶段共享。

执行此操作后,您还可以将其视为管道 UI 中已发布的工件。

# Publish pipeline artifacts
# Publish (upload) a file or directory as a named artifact for the current run
- task: PublishPipelineArtifact@1
  inputs:
    targetPath: '$(Pipeline.Workspace)' 
    artifactName: # 'drop'
Run Code Online (Sandbox Code Playgroud)

另外,可以在该阶段结束时进行的另一项内部检查是包含一个 powershell 脚本来查看您正在工作的目录的内容:

-powershell: Get-ChildItem -Path 'Insert root path' -recurse
Run Code Online (Sandbox Code Playgroud)