【问题标题】:CTest Error on MacOS: Test Executable not foundMacOS 上的 CTest 错误:找不到测试可执行文件
【发布时间】:2020-11-17 18:01:59
【问题描述】:

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

之前我的项目没有正确构建。但现在除了 MacOS 上的小故障外,整个管道都成功运行(感谢 Stack Overflow 社区)。我已经更新了我的问题,现在它会告诉我问题是什么以及我如何解决它,以便它可能对像我这样刚接触 CI 世界的其他人有所帮助。

编辑 1

之前我的 CMake 任务没有触发构建过程。这是因为我没有向 CMake 提供任何命令行参数。我所做的只是:

- task: CMake@1
  displayName: Generate CMake Cache
  inputs:
    workingDirectory: build

我假设 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)

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

编辑 3

在 MacOS 上的测试阶段,我收到了错误:

测试项目 /home/vsts/work/1/s/Debug 开始1:StringOperations_CaseIgnore 找不到可执行文件/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 用户/runner/work/1/s/Debug/Tests/StringOperations/TestStringOperations 用户/runner/work/1/s/Debug/Tests/StringOperations/TestStringOperations 用户/runner/work/1/s/Debug/Tests/StringOperations/Debug/TestStringOperations 用户/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 1/1 测试 #1:StringOperations_CaseIgnore ......***未运行 0.00 秒

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

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

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

编辑 4

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

ls -l Debug/Tests/StringOperations

这是输出:

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

这确认测试可执行文件 (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)

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

例如: CTest can not find executable fileCMake: How to specify directory where ctest should look for executables?

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

你能帮我解决这个问题吗?也欢迎就该文件的整体实施提出任何建议。

【问题讨论】:

  • 显然这是因为Cmake任务没有正确执行,没有生成build文件夹。我们需要检查 cmake 任务以使其正确构建。您可以检查是否可以在本地计算机上正确构建它,并在您的问题中分享 cmake 构建日志。
  • 构建过程在我的本地机器上运行良好。
  • Azure 管道阶段不共享本地状态,因此build 目录在Test 阶段中​​不存在。要在阶段之间传输文件,您需要使用artifacts。但是,我建议在您更熟悉 Azure 管道之前避免使用多个阶段,并且只需在单个阶段中运行构建+测试。请注意,与大多数 CI 服务不同,AZP 将在非零命令退出后继续运行命令除非您使用 set -e(用于 bash)或类似的检查。
  • 请注意,上面的 cmets 指的是我的构建过程没有开始的时间。现在我有一个完全不同的问题。

标签: c++ cmake continuous-integration azure-pipelines ctest


【解决方案1】:

尝试在构建后运行Publish Pipeline Artifact task。正如在 cmets 中所避免的那样,这将发布您的构建内容并允许跨阶段共享它。

完成此操作后,您还可以在管道的 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'

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

-powershell: Get-ChildItem -Path 'Insert root path' -recurse

【讨论】:

  • 我已经成功地完成了构建过程。我发现在测试阶段将无法访问构建的对象。因此,我将构建的对象发布为工件,然后在测试时下载它,就像您在上面演示的那样。请参阅我编辑的问题。
  • 我可以看看。如果原始问题得到正确回答,我建议关闭此问题。这样您就可以在 Cmake 测试中获得更有针对性的受众。
猜你喜欢
  • 1970-01-01
  • 2021-10-26
  • 2020-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-28
  • 2017-07-03
  • 2011-01-21
相关资源
最近更新 更多