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 文件
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上的管道日志。
你能帮我解决这个问题吗?也欢迎有关此文件的整体实施的任何建议。
尝试在构建后运行发布管道工件任务。正如评论中所回避的那样,这将发布您的构建内容并允许其跨阶段共享。
执行此操作后,您还可以将其视为管道 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)