Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to detect if running under WSL? #4071

Closed
AgnerF opened this issue May 28, 2019 · 20 comments
Closed

How to detect if running under WSL? #4071

AgnerF opened this issue May 28, 2019 · 20 comments

Comments

@AgnerF
Copy link

AgnerF commented May 28, 2019

How do you detect if running under WSL?

C compilers in Mingw and Cygwin have preprocessing defines that allow you to identify the system. Is there a WSL preprocessing define or some other method for identifying the system? If not, please make a preprocessing define that gives a WSL version number.

You may claim that this is a genuine Linux (Ubuntu or whatever), but it is not. The floating point control word is set to reduced precision, and this causes a lot of problems. (Why has issue #830 never been fixed?). Also, of course, there is no GUI in WSL.

@floodkoff
Copy link

I think your question should be addressed to the gcc or clang compiler team not WSL

@benhillis
Copy link
Member

The Windows version is present in our kernel command line (/proc/version, or uname -a).

@xtremeperf
Copy link

if [[ $(grep Microsoft /proc/version) ]]; then
echo "Bash is running on WSL"
fi

@AgnerF
Copy link
Author

AgnerF commented May 29, 2019

Thanks for the comments. I would like to detect WSL from a preprocessing directive when compiling a program. Something like #ifdef __ WSL __. There are special versions of gcc for Mingw and Cygwin, but as I understand it, there is no special version of gcc for WSL. Is there any way that a __ WSL __ define can be added automatically when the compiler is running under WSL?

@floodkoff
Copy link

@AgnerF it is a kind of define that you can do yourself. You don't need compiler support for that. Just generate config.h file using the build system of your choice. Here is how to do it in meson for example:
meson.build file

# meson.build
grep = find_program('grep')
runcmd = run_command(grep, '-q', 'Microsoft', '/proc/version')

confdata = configuration_data()
if runcmd.returncode() != 0
    confdata.set('WTL', 0)
else
    confdata.set('WTL', 1)
endif

configure_file(
    input : 'config.h.in',
    output : 'config.h',
    configuration : confdata)

config.h.in file

#mesondefine WTL

Meson will generate config.h with the following contents:

#define WTL 1

WTL define will be 1 under WTL and 0 under any other linux.

@therealkenc
Copy link
Collaborator

#423

@b-hayes
Copy link

b-hayes commented Jun 26, 2020

Is there a way to determine WSL1 vs WSL2. I normally use the uname -a and check for Linux and Microsoft but both will say that.

@mirabilos
Copy link

@AgnerF the idea here is that unmodified Linux binaries run on WSL (and that binaries compiled on WSL are unmodified Linux binaries), so you’ll have to do a run-time check, not a compile-time check.

@flickerfly
Copy link

A little correction/update for what @xtremeperf said, you need to grep case insensitive. On my (maybe newer?) WSL, it is not a capital M, just "microsoft" so use this for greater confidence.

if [[ $(grep -i Microsoft /proc/version) ]]; then
    echo "Bash is running on WSL"
fi

@b-hayes
Copy link

b-hayes commented Aug 23, 2022

@flickerfly its actually WSLv2 using lowecase from my experience. If Ya'll are interested here's what I use to detect all operating environments that I use.

#!/usr/bin/env bash

unameOut=$(uname -a)
case "${unameOut}" in
    *Microsoft*)     OS="WSL";; #wls must be first since it will have Linux in the name too
    *microsoft*)     OS="WSL2";; 
    Linux*)     OS="Linux";;
    Darwin*)    OS="Mac";;
    CYGWIN*)    OS="Cygwin";;
    MINGW*)     OS="Windows";; 
    *Msys)     OS="Windows";;
    *)          OS="UNKNOWN:${unameOut}"
esac

if [[ ${OS} == "Mac" ]] && sysctl -n machdep.cpu.brand_string | grep -q 'Apple M1'; then
    #Check if its an M1. This check should work even if the current processes is running under x86 emulation.
    OS="MacM1"
fi

echo ${OS};

@mirabilos
Copy link

mirabilos commented Oct 11, 2022 via email

@b-hayes
Copy link

b-hayes commented Oct 12, 2022

The difference changes between WSLv1 and WSLv2 hence why I have the distinction in the script I provided above your comment.

@mirabilos
Copy link

mirabilos commented Oct 12, 2022 via email

@b-hayes
Copy link

b-hayes commented Oct 12, 2022

That's correct. The difference in case changes from WSL to WSLv2. As per my script above, WSLv2 uses lowercase.

@mirabilos
Copy link

mirabilos commented Oct 13, 2022 via email

@b-hayes
Copy link

b-hayes commented Oct 13, 2022

Yeah, that's what I meant sorry for the confusion.

@cuynu
Copy link

cuynu commented Oct 6, 2023

is there anyway to detect if running under WSL but for java jar runtime?

@b-hayes
Copy link

b-hayes commented Oct 11, 2023

@cuynu you could run a shell command in Java and use the same approach as my script does: #4071 (comment)

@durantschoon
Copy link

if [[ $(grep Microsoft /proc/version) ]]; then echo "Bash is running on WSL" fi

this needs to be grep -i Microsoft /proc/version for case insensitive search now.

@RokeJulianLockhart
Copy link

I think this should be transferred to a https://github.com/microsoft/WSL/discussions/new?category=q-a.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests