首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Gitlab运行程序使用Docker-Windows

Gitlab运行程序使用Docker-Windows
EN

Stack Overflow用户
提问于 2021-03-29 10:02:10
回答 1查看 842关注 0票数 1

我试图使用Windows中的Docker来创建一个Gitlab来构建一个C++应用程序。到目前为止还能用,但我想还有更好的方法。我所做的是:

这是我最初的码头集装箱:

代码语言:javascript
运行
复制
FROM mcr.microsoft.com/windows/servercore:2004

# Restore the default Windows shell for correct batch processing.
SHELL ["cmd", "/S", "/C"]

# Download the Build Tools bootstrapper.
ADD https://aka.ms/vs/16/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe

# Install Build Tools with the Microsoft.VisualStudio.Workload.AzureBuildTools workload, excluding workloads and components with known issues.
RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
    --installPath C:\BuildTools `
    --add Microsoft.VisualStudio.Workload.VCTools `
    --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
    --add Microsoft.VisualStudio.Component.VC.CMake.Project `
    --add Microsoft.VisualStudio.Component.Windows10SDK.19041 `
    --locale en-US `
 || IF "%ERRORLEVEL%"=="3010" EXIT 0

# Define the entry point for the docker container.
# This entry point starts the developer command prompt and launches the PowerShell shell.
ENTRYPOINT ["cmd","/k", "C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]

我的..gitlab ci.yml看起来是这样的:

代码语言:javascript
运行
复制
build Docker Windows:
  image: buildtools2019_core
  stage: build
  tags:
    - win-docker
  script:
    - mkdir build
    - cd build
    - cmake -DCMAKE_BUILD_TYPE=Release -DenableWarnings=ON  -G Ninja -DCMAKE_MAKE_PROGRAM=Ninja ../
    - ninja

到目前为止,这是可行的,所有的东西都是正确的。但是,主要的问题是,如果构建失败,作业无论如何都会成功。我怀疑我的入口点是错误的,因为powershell是在cmd内部执行的,并且只检查cmd的退出代码,这总是成功的。

所以我试着直接用powershell作为入口点。我需要通过vcvars64.bat设置环境变量,但这并不简单。我试图执行"Developer Powershell for VS 2019“,但无法直接在入口点执行链接,链接如下所示:

代码语言:javascript
运行
复制
"C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -noe -c "&{Import-Module """C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"""; Enter-VsDevShell 6f66c5f6}"

我不会放弃它,理解它所做的事情,而且散列也因安装而异。而且,简单地使用这个作为入口点是行不通的。然后,我尝试使用从"https://github.com/nightroman/PowerShelf/blob/master/Invoke-Environment.ps1"“获取的Invoke-Environment脚本。这允许我从powershell执行.bat文件,如下所示:

代码语言:javascript
运行
复制
Invoke-Environment C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat

但要做到这一点,我需要把这个函数添加到我的个人资料中,据我所知。为此,我将其复制到"C:\Windows\system32\WindowsPowerShell\v1.0\profile.ps1“,以便所有用户都可以访问它。

在我的Docker文件中,我添加了:

代码语言:javascript
运行
复制
COPY Invoke-Environment.ps1 C:\Windows\system32\WindowsPowerShell\v1.0\profile.ps1

并将入口点改为:

代码语言:javascript
运行
复制
ENTRYPOINT ["C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe", "-NoExit", "-NoLogo", "-ExecutionPolicy", "Bypass", "Invoke-Environment C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat"]

但这没有正确初始化环境变量。另外,gitlab-runner没有找到"Invoke-Environment“。我的最后一招是编写一个小脚本(Init64.ps1),它使用vcvars64.bat执行调用-Environment函数:

代码语言:javascript
运行
复制
function Invoke-Environment {
    param
    (
        # Any cmd shell command, normally a configuration batch file.
        [Parameter(Mandatory=$true)]
        [string] $Command
    )

    $Command = "`"" + $Command + "`""
    cmd /c "$Command > nul 2>&1 && set" | . { process {
        if ($_ -match '^([^=]+)=(.*)') {
            [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2])
        }
    }}
}

Invoke-Environment C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat

我在码头上复制了这个

代码语言:javascript
运行
复制
COPY Init64.ps1 Init64.ps1

并使用这个入口点:

代码语言:javascript
运行
复制
ENTRYPOINT ["C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe"]

在我的构建脚本中,我需要手动调用它来设置变量:

代码语言:javascript
运行
复制
build Docker Windows:
  image: buildtools2019_core
  stage: build
  tags:
    - win-docker
  script:
    - C:\Init64.ps1
    - mkdir build
    - cd build
    - cmake -DCMAKE_BUILD_TYPE=Release -DenableWarnings=ON  -G Ninja -DCMAKE_MAKE_PROGRAM=Ninja ../
    - ninja

现在,一切都按预期工作,构建可以工作,只有在构建成功时,工作才会成功。

但是,我更愿意在入口点设置我的环境,这样我就不必在构建脚本中这样做了。

有更好的方法吗?也可以随意建议我可以做的任何改进。

EN

回答 1

Stack Overflow用户

发布于 2022-02-25 15:44:09

好的,经过一些挣扎之后,下面是正确加载环境导出错误级别/返回值的entry.bat

代码语言:javascript
运行
复制
REM Load environment
call C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat

REM If there are no parameters call cmd
IF [%1] == [] GOTO NOCALL

REM If there are parameters call cmd with /S for it to exit directly
cmd /S /C "%*"
exit %errorlevel%

:NOCALL
cmd
exit %errorlevel%
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66852183

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档