jborean93 / omi

Open Management Infrastructure
Other
108 stars 13 forks source link

M1 Mac OpenSSL Version #49

Closed jeff-simeon closed 2 years ago

jeff-simeon commented 2 years ago

Just trying this on an M1 Mac for the first time and getting this error

SUMMARY

Getting a processor architecture mismatch error.

Reason: tried: '/opt/homebrew/Cellar/openssl@3/3.0.1/lib//libssl.3.dylib' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')), '/usr/local/lib/libssl.3.dylib' (no such file), '/usr/lib/libssl.3.dylib' (no such file), '/opt/homebrew/Cellar/openssl@3/3.0.1/lib/libssl.3.dylib' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')), '/usr/local/lib/libssl.3.dylib' (no such file), '/usr/lib/libssl.3.dylib' (no such file)
LIBMI VERSION

2.3.0

OS / ENVIRONMENT

Mac OS 12.0.1 M1 Max

Is there a way to work around this?

Thanks.

jborean93 commented 2 years ago

You need to ensure the linked OpenSSL library architecture matches the architecture used by PowerShell, they cannot be mixed. The Install-WSMan step should check all this for you and set it up properly. Did you use that to install the library? If so can you share the output of Install-WSMan -Verbose?

jeff-simeon commented 2 years ago

I just did brew install openssl Is there a different version I should install? Output below

Install-WSMan: A parameter cannot be found that matches parameter name 'Verbose?'.
PS /Users/jeffnevins/dev/M365Management> Install-WSMan -Verbose 
VERBOSE: Attempting to get OpenSSL info with /opt/homebrew/bin/brew --prefix openssl
STDOUT: /opt/homebrew/opt/openssl@3

STDERR: 

RC: 0
VERBOSE: Checking arch information for '/opt/homebrew/opt/openssl@3/lib/libcrypto.dylib' and '/opt/homebrew/opt/openssl@3/lib/libssl.dylib'
VERBOSE: Binary at '/opt/homebrew/opt/openssl@3/lib/libcrypto.dylib' does not exist - cannot test architecture
VERBOSE: Attempting to get OpenSSL info with /opt/homebrew/bin/brew --prefix openssl@3
STDOUT: /opt/homebrew/opt/openssl@3

STDERR: 

RC: 0
VERBOSE: Checking arch information for '/opt/homebrew/opt/openssl@3/lib/libcrypto.dylib' and '/opt/homebrew/opt/openssl@3/lib/libssl.dylib'
VERBOSE: Binary at '/opt/homebrew/opt/openssl@3/lib/libcrypto.dylib' does not exist - cannot test architecture
VERBOSE: Attempting to get OpenSSL info with /opt/homebrew/bin/brew --prefix openssl@1.1
STDOUT: /opt/homebrew/opt/openssl@1.1

STDERR: 

RC: 0
VERBOSE: Checking arch information for '/opt/homebrew/opt/openssl@1.1/lib/libcrypto.dylib' and '/opt/homebrew/opt/openssl@1.1/lib/libssl.dylib'
VERBOSE: Binary at '/opt/homebrew/opt/openssl@1.1/lib/libcrypto.dylib' does not exist - cannot test architecture
VERBOSE: Attempting to get OpenSSL info with /opt/homebrew/bin/brew --prefix openssl
STDOUT: /opt/homebrew/opt/openssl@3

STDERR: 

RC: 0
VERBOSE: Checking arch information for '/opt/homebrew/opt/openssl@3/lib/libcrypto.dylib' and '/opt/homebrew/opt/openssl@3/lib/libssl.dylib'
VERBOSE: Binary at '/opt/homebrew/opt/openssl@3/lib/libcrypto.dylib' does not exist - cannot test architecture
VERBOSE: Attempting to get OpenSSL info with /opt/homebrew/bin/brew --prefix openssl@3
STDOUT: /opt/homebrew/opt/openssl@3

STDERR: 

RC: 0
VERBOSE: Checking arch information for '/opt/homebrew/opt/openssl@3/lib/libcrypto.dylib' and '/opt/homebrew/opt/openssl@3/lib/libssl.dylib'
VERBOSE: Binary at '/opt/homebrew/opt/openssl@3/lib/libcrypto.dylib' does not exist - cannot test architecture
VERBOSE: Attempting to get OpenSSL info with /opt/homebrew/bin/brew --prefix openssl@1.1
STDOUT: /opt/homebrew/opt/openssl@1.1

STDERR: 

RC: 0
VERBOSE: Checking arch information for '/opt/homebrew/opt/openssl@1.1/lib/libcrypto.dylib' and '/opt/homebrew/opt/openssl@1.1/lib/libssl.dylib'
VERBOSE: Binary at '/opt/homebrew/opt/openssl@1.1/lib/libcrypto.dylib' does not exist - cannot test architecture
VERBOSE: Failed to find OpenSSL with homebrew, falling back to port
VERBOSE: Failed to find port at 'port'
VERBOSE: Failed to find port at '/opt/local/bin/port'
VERBOSE: Host Info:
jborean93 commented 2 years ago

So the code has tried openssl, openssl@3, openssl@1.1 for both brew and /opt/homebrew/bin/brew but it's failed to find any valid installs of those packages. Can you share the value of [System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture when you run PowerShell and check if there are files in /opt/homebrew/opt/openssl@3/lib?

jeff-simeon commented 2 years ago

I'm running on PowerShell 7.2 with arm64

[System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture
Arm64

I retried with openssl 1.1 and am getting a similar, but not quite the same error.

/libpsrpclient.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e')), '/usr/local/lib/libpsrpclient.dylib' (no such file), '/usr/lib/libpsrpclient.dylib' (no such file)

It sounds like I don't have the arm64 version of openssl installed. Is there a special command to install that version?

jborean93 commented 2 years ago

brew should do just that if you are running their arm64 variant. You can do lipo -archs /path/to/lib to verify what it is set at. I would verify all the libraries that are in use are set to the right version

lipo -archs "$( dirname $( which pwsh ) )/libpsrpclient.dylib"
lipo -archs "$( dirname $( which pwsh ) )/libmi.dylib"

You should also check libssl.dylib and libcrypto.dylib for whatever the symlinks in the pwsh dir is pointing to (they will have a version number in the filename). This should all be done by Install-WSMan but it is failing to find the OpenSSL libs for some reason so it's not installing the proper libmi/libpsrpclient libs and thus would be using whatever PowerShell ships with (which is not arm64).

jeff-simeon commented 2 years ago

I'm pretty sure my code is locating the correct libraries since I can see my NativeLibrary.SetDllImportResolver getting called.

I have a post build script that looks like this:


  <Target Name="Set PowerShell dylibs" Condition="Exists('/opt/homebrew/opt/openssl')">
    <PropertyGroup>
      <PSWSManVersion>2.2.1</PSWSManVersion>
      <LibPath>/opt/homebrew/opt/openssl/lib/</LibPath>
    </PropertyGroup>
    <Message Text="Installing..."/>
    <Exec Condition="!Exists('bin/PSWSMan/$(PSWSManVersion)/lib/macOS-3/libmi.dylib')" Command="pwsh -Command Save-Module PSWSMan -RequiredVersion $(PSWSManVersion) -Path bin" />
    <ItemGroup>
      <PowerShellSdkDylibs Include="bin/PSWSMan/$(PSWSManVersion)/lib/macOS-3/*.dylib" />
    </ItemGroup>
    <Exec Command="install_name_tool -change @loader_path/libssl.3.dylib $(LibPath)/libssl.3.dylib '%(PowerShellSdkDylibs.FullPath)'" />
    <Exec Command="install_name_tool -change @loader_path/libcrypto.3.dylib $(LibPath)/libcrypto.3.dylib '%(PowerShellSdkDylibs.FullPath)'" />
    <ItemGroup>
      <Content Include="@(PowerShellSdkDylibs)" CopyToOutputDirectory="Always" Visible="false">
        <Link>%(Filename)%(Extension)</Link>
      </Content>
    </ItemGroup>
  </Target>

and I see it getting linked at build time

The import resolver looks like this:

        public static IntPtr ImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
        {
            var localPath = Path.Combine(AppContext.BaseDirectory, $"{libraryName}.dylib");
            if (File.Exists(localPath)) libraryName = localPath;
            return NativeLibrary.Load(libraryName, assembly, searchPath);
        }
jborean93 commented 2 years ago

Oh you aren't using Install-WSMan but your own custom setup for a C# application. You need to ensure that whatever libssl.3.dylib and libcrypto.3.dylib is pointing to the same architecture as your running process. Use the lipo -archs command to verify that.

jeff-simeon commented 2 years ago

I don't see multiple archs available in the openssl bin folder. Is there a different download I need to get different archs?

jborean93 commented 2 years ago

Check the lib folder using the lipo command I shared. It should tell you what archs they've been compiled against. This must match whatever pwsh is running as or else you get the failures you see here. In the example of brew it will compile the package in whatever architecture brew is running as so check you have the arm64 version of that.

jeff-simeon commented 2 years ago
libcrypto.3.dylib   libcrypto.dylib     libssl.a        ossl-modules
@jeffs-mbp lib % lipo -archs libcrypto.dylib 
arm64
@jeffs-mbp lib % lipo -archs libssl.dylib   
arm64
@jeffs-mbp lib % lipo -archs libssl.3.dylib 
arm64
@jeffs-mbp lib % lipo -archs libcrypto.3.dylib 
arm64

And I do see that libmi and libpsrpclient are mismatched, as you suspected.

@jeffs-mbp net6.0 % lipo -archs libmi.dylib         
x86_64
@jeffs-mbp net6.0 % lipo -archs libpsrpclient.dylib 
x86_64

But I only see these two dylibs in my PSWSMan folder image

So what do I need to do to get the PSWSMan dylibs for the right architecture?

Or in lieu of that, I can compile our app for x64 and utilize x64 emulation the whole way through...but if I do that, how do I install the x64 version of openssl even though I'm on arm64?

jborean93 commented 2 years ago

Make sure you are actually using the files from the 2.3.0 release, that's when these libraries were compiled as a universal lib https://github.com/jborean93/omi/pull/34.

image

jeff-simeon commented 2 years ago

2.3.0 worked! Thank you.