microsoft / vcpkg

C++ Library Manager for Windows, Linux, and MacOS
MIT License
22.18k stars 6.16k forks source link

[powershell] Vcpkg sourced powershell scripts don't work in ConstrainedLanguage mode #17890

Open Cazadorro opened 3 years ago

Cazadorro commented 3 years ago

Describe the bug A clear and concise description of what the bug is.

Related (but this problem is way more pervasive than this issue) https://github.com/microsoft/vcpkg/issues/5229 though I don't appear to have this issue, the bat file works fine for me.

Vcpkg has run into this issue https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode-and-the-dot-source-operator/

I don't understand powershell and will never touch it, but from what I understand powershell works in a restricted syntactic mode when ConstrainedLanguage is on, which I guess is configured by default for non-privledged accounts in some companies, and when TEMP or TMP is used ie, AppData/Local/Temp (appdata, the output directory does not allow for unconstrained usage of powershell.

So I don't have a way to waive this ConstrainedLanguage mode with out going to admin mode or changing TEMP and TMP user environmental variables, and as you'll see, this straight up breaks everything with vcpkg.

Environment

To Reproduce Steps to reproduce the behavior:

  1. Create a CMake based project
  2. Use -DCMAKE_TOOLCHAIN_FILE=[pathtovcpkg]/vcpkg/scripts/buildsystems/vcpkg.cmake
  3. Example:

    
    "[pathtocmake]/cmake.exe" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=[pathtovcpkg]/vcpkg/scripts/buildsystems/vcpkg.cmake -G "CodeBlocks - NMake Makefiles" [projectdir]\myproject
    -- The C compiler identification is MSVC 19.28.29337.0
    -- The CXX compiler identification is MSVC 19.28.29337.0
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - failed
    -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe
    -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe - broken
    CMake Error at [cmakepath]/cmake-3.19/Modules/CMakeTestCCompiler.cmake:66 (message):
    The C compiler
    
    "C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe"
    
    is not able to compile a simple test program.
    
    It fails with the following output:
    
    Change Dir: [projectpath]/myproject/cmake-build-debug/CMakeFiles/CMakeTmp
    
    Run Build Command(s):nmake /nologo cmTC_ddd2b\fast &&   "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\bin\HostX64\x64\nmake.exe"  -f CMakeFiles\cmTC_ddd2b.dir\build.make /nologo -L                  CMakeFiles\cmTC_ddd2b.dir\build
    Building C object CMakeFiles/cmTC_ddd2b.dir/testCCompiler.c.obj
        C:\PROGRA~2\MIB055~1\2019\PROFES~1\VC\Tools\MSVC\1428~1.293\bin\Hostx64\x64\cl.exe @[myuser]AppData\Local\Temp\nm6846.tmp
    testCCompiler.c
    Linking C executable cmTC_ddd2b.exe
        "[cmakepath]\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\cmTC_ddd2b.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x64\mt.exe --manifests -- C:\PROGRA~2\MIB055~1\2019\PROFES~1\VC\Tools\MSVC\1428~1.293\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\cmTC_ddd2b.dir\objects1.rsp @[userpath]\AppData\Local\Temp\nm6885.tmp
        C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -executionpolicy Bypass -file [vcpkgpath]/vcpkg/scripts/buildsystems/msbuild/applocal.ps1 -targetBinary [projectpath]/myproject/cmake-build-debug/CMakeFiles/CMakeTmp/cmTC_ddd2b.exe -installedDir [vcpkgpath]/vcpkg/installed/x64-windows/debug/bin -OutVariable out
    [vcpkgpath]\vcpkg\scripts\buildsystems\msbuild\applocal.ps1 : Cannot dot-source this 
    command because it was defined in a different language mode. To invoke this command without importing its contents, 
    omit the '.' operator.
        + CategoryInfo          : InvalidOperation: (:) [applocal.ps1], NotSupportedException
        + FullyQualifiedErrorId : DotSourceNotSupported,applocal.ps1
    
    NMAKE : fatal error U1077: 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' : return code '0x1'
    Stop.
    NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\bin\HostX64\x64\nmake.exe"' : return code '0x2'
    Stop.
    
    CMake will not be able to correctly generate this project.
    Call Stack (most recent call first):
    CMakeLists.txt:2 (project)

-- Configuring incomplete, errors occurred! See also "[projectpath]/myproject/cmake-build-debug/CMakeFiles/CMakeOutput.log". See also "[projectpath]/myproject/cmake-build-debug/CMakeFiles/CMakeError.log".


This same thing *also happens* when building some dependencies, for example I ran into this with "libconv" (though it is hidden behind another log file)

CMake Error at scripts/cmake/vcpkg_execute_required_process.cmake:105 (message): Command failed: [vcpkgdir]vcpkg/downloads/tools/powershell-core-7.1.3-windows/pwsh.exe -noprofile -executionpolicy Bypass -nologo -file [vcpkgdir]vcpkg/scripts/buildsystems/msbuild/applocal.ps1 -targetBinary [vcpkgdir]vcpkg/packages/libiconv_x64-windows/tools/libiconv/bin/iconv.exe -installedDir [vcpkgdir]vcpkg/packages/libiconv_x64-windows/bin Working Directory: [vcpkgdir]vcpkg Error code: 1 See logs for more information: [vcpkgdir]\vcpkg\buildtrees\libiconv\copy-tool-dependencies-err.log

Call Stack (most recent call first): scripts/cmake/vcpkg_copy_tool_dependencies.cmake:34 (vcpkg_execute_required_process) scripts/cmake/vcpkg_copy_tool_dependencies.cmake:44 (search_for_dependencies) ports/libiconv/portfile.cmake:40 (vcpkg_copy_tool_dependencies) scripts/ports.cmake:142 (include)

Error: Building package libiconv:x64-windows failed with: BUILD_FAILED Please ensure you're using the latest portfiles with .\vcpkg update, then submit an issue at https://github.com/Microsoft/vcpkg/issues including: Package: libiconv:x64-windows Vcpkg version: 2021-05-05-9f849c4c43e50d1b16186ae76681c27b0c1be9d9

Additionally, attach any relevant sections from the log files above.



Here is the corresponding text found in [vcpkgdir]\vcpkg\buildtrees\libiconv\copy-tool-dependencies-err.log :

`applocal.ps1: Cannot dot-source this command because it was defined in a different language mode. To invoke this command without importing its contents, omit the '.' operator.`

**Expected behavior**
This not to be an issue

**Failure logs** 
see above

**Additional Context**

Two things fix this on the user end, at least for me, Launching everything in admin mode (not a real workable solution) and changing TMP and TEMP environmental variables to a place my non admin account has write access to (Not workable on a system scale, I don't know what the side effects of this are for all future programs).  I'm guessing either the powershell scripts need to be fixed, removed, or we need to be able to specify temp for *just* vcpkg, which if possible, does not appear to be easily visible how to do so. 
BillyONeal commented 3 years ago

I'm not sure there are practical things vcpkg can do to work around this as long as we rely on any powershell at all :(

Cazadorro commented 3 years ago

@BillyONeal A few notes:

BillyONeal commented 3 years ago

Doesn't VCPKG rely on the existence of cmake? Couldn't it just use CMake scripts to do half the stuff it needs to?

Not in applocal.ps1 -- that needs to be small / cheap to copy next to the platform msbuild scripts in %APPDATA%.

Conan gets around this by simply using python for its scripting on eveyr platform IIRC, but VCPKG can't be using powershell on linux can it? So what stops whatever solution is available there from working on windows?

Linux does not have the equivalent of the applocal.ps1 feature in the first place. It's less necessary there because we restrict things in general to static linking so there would be no dynamic libraries to applocal.

Would it not be possible for VCPKG to not to just allow user to specify a custom directory for whatever this PowerShell stuff is using it for

It needs to be next to the msbuild props and targets so that they can find applocal.ps1.

I think truly resolving this (and a host of other problems we've had with powershell) means we need to rewrite what applocal.ps1 does in vcpkg.exe.

dg0yt commented 3 years ago

I think truly resolving this (and a host of other problems we've had with powershell) means we need to rewrite what applocal.ps1 does in vcpkg.exe.

Can't it be written in CMake? I am using CMake's BundleUtilities for years, with shared libs on Windows, macOS, Linux, for Qt and GDAL and the libs and plugins behind. Since CMake 3.16, there is even file(GET_RUNTIME_DEPENDENCIES ....)

BillyONeal commented 3 years ago

I think truly resolving this (and a host of other problems we've had with powershell) means we need to rewrite what applocal.ps1 does in vcpkg.exe.

Can't it be written in CMake? I am using CMake's BundleUtilities for years, with shared libs on Windows, macOS, Linux, for Qt and GDAL and the libs and plugins behind. Since CMake 3.16, there is even file(GET_RUNTIME_DEPENDENCIES ....)

No, we can't assume CMake is present (unless we could copy it next to the appdata msbuild props and targets). And that would still be a complete rewrite. If we're going rewrite we may as well do so in a way won't ever bring this problem back again.

SteveL-MSFT commented 3 years ago

If an enterprise restricts use of PowerShell to only constrained language mode, then, by design, you can't let untrusted scripts run with full language mode. A signed and trusted (signer is trusted) PowerShell script will always run in full language mode, but that may not be practical to sign every script in your enterprise unless your enterprise has invested in enabling that. We can't have some tools break out of this sandbox as those scripts may be malicious.

BillyONeal commented 2 years ago

Another user reporting similar issues: https://www.reddit.com/r/cpp/comments/six9bk/comment/hvc8wm7/?utm_source=share&utm_medium=web2x&context=3

ghlecl commented 2 years ago

I have a similar/the same issue. I am trying to build openssl. I am using MSVC 2019 (updated this morning, 2022-05-25). The release build works, but the x64-windows-dbg fails. When looking at the error, it says:

Cannot dot-source this command because it was defined in a different language mode.
To invoke this command without importing its contents, omit the '.' operator.

That message appears in the file:

C:\local\vcpkg\buildtrees\openssl\copy-tool-dependencies-0-err.log

It is the only thing in the file (minus some terminal color coding I think and the name of the file it comes from: applocal.ps1.

I work in a hospital and the IT department seems to prevent any sourcing of files and always set PowerShell to restricted mode (I have not tested nor am I knowledgeable enough in PowerShell to know if it is only TEMP, TMP or the whole computer).

This prevents me from using vcpkg... :-(

ghlecl commented 2 years ago

Just as a follow up, I actually created a second project (still trying to use vcpkg as it would probably simplify dependency management...) and this second project does not have openssl as a dependency. This project lists only catch2 and CTRE as its dependencies. In that project, the configure/generate cycle of CMake gets passed the installation of the vcpkg projects (I use manifest mode).

That said, when I go on to simply build a main.cpp which is the basic C++ hello world, project configuration and generation in CMake fails, and again, it's while trying to source applocal.ps1.

So basically, because the hospital where I work puts PowerShell in restricted mode (or something like that), I cannot use vcpkg at all it would seem.

Not sure you can/will do anything about that, but thought I would add a datapoint to the conversation.