I added bash on windows to windows terminal by editing the settings.json file, when I try to compile a simple hello world written in c++ it throws an error that gcc or g++ is not detected How to properly add MSYS bash terminal so that I can compile file from windows terminal
In settings.json I added the path to the bash shell like so :
{
"commandline": "powershell.exe",
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"hidden": false,
"name": "Windows PowerShell"
},
{
"guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}",
"hidden": false,
"name": "Azure Cloud Shell",
"source": "Windows.Terminal.Azure"
},
{
"commandline": "C:\\msys64\\usr\\bin\\bash.exe -i -l",
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"hidden": false,
"name": "msys2"
},
{
"guid": "{495d29da-4bfb-4956-abd8-ed1760703232}",
"commandline": "cmd.exe",
"hidden": false,
"name": "cmd.exe"
}
Part 1 of 2. (I had to split this answer into two parts because it's too long, > 30k characters).
Jump to Part 2 of 2.
...so you can build native Windows applications with gcc on Windows.
Tested on the latest version of MSYS2, msys2-x86_64-20231026.exe
, from https://www.msys2.org/, on Windows 11, on 31 Oct. 2023, as a spooky treat.
As a more beginner-friendly, thorough, and customized version of @Weed Cookie's answer, here are additional details I and other beginners are sure to need.
Note that MSYS2 includes MinGW-w64 and the Pacman package manager, and is a powerful, Linux-like terminal and GCC and LLVM (clang) build environment for Windows. It is akin to Cygwin, and Git Bash from Git for Windows uses the MSYS2 mingw64 environment. However, MSYS2 is optimized for building software, so for using Git they recommend you also install and use Git for Windows's Git Bash separately. So, you can think of regular MSYS2 as a native Windows build environment, and Git Bash as a native Windows git
and developer environment based on MSYS2.
MSYS2 is kind of like a light version of Linux running inside Windows. As compared to WSL (Windows Subsystem for Linux), which is Linux on Windows, MSYS2 has this huge caveat: from https://www.msys2.org/docs/what-is-msys2/ (emphasis added):
MSYS2 allows you to build native Windows programs, while with WSL you can only cross compile them which makes things more complicated.
So:
git
commands in native Windows.gcc -Wall -Wextra -Werror -O3 -std=gnu17 hello_world_extra_basic.c -o bin/a -lm && bin/a
Here are the 7 MSYS2 shell/environment types:
msys
and msys2
(same thing now) - the base MSYS2 tool; all other environments below inherit from this one; contains the GCC 64-bit compiler and Cygwin C library. Is mostly Posix-compatible, including for sockets (see the socket demo in Part 2 of my answer).mingw32
- Minimalist GNU for Windows 32-bit; contains GCC 32-bit compilermingw64
- Minimalist GNU for Windows 64-bit; contains GCC 64-bit compilerucrt64
- UCRT (Universal C Runtime) 64-bit; contains GCC 64-bit compiler; MSYS2 says: "If you are unsure, go with UCRT64 [this one]." See this comment too. Works by default only on Windows 10 or later.clang64
- contains the LLVM/Clang 64-bit compilerclang32
- contains the LLVM/Clang 32-bit compilerclangarm64
- contains the LLVM/Clang 64-bit ARM (AArch64) compilerFrom: https://www.msys2.org/docs/environments/:
Also from https://www.msys2.org/docs/environments/ (emphasis added):
MSYS2 comes with different environments and the first thing you have to decide is which one to use. The differences among the environments are mainly environment variables, default compilers/linkers, architecture, system libraries used etc. If you are unsure, go with UCRT64.
The MSYS environment...is always active. All the other environments inherit from the MSYS environment and add various things on top of it.
For example, in the UCRT64 environment the
$PATH
variable starts with/ucrt64/bin:/usr/bin
so you get all ucrt64 based tools as well as all msys tools.The active environment is selected via the
MSYSTEM
environment variable. SettingMSYSTEM
toUCRT64
and starting a login shell will put you in that environment.
For details on GCC vs LLVM/Clang and MSVCRT vs UCRT, see here: https://www.msys2.org/docs/environments/.
UCRT (Universal C Runtime) is a newer version which is also used by Microsoft Visual Studio by default. It should work and behave as if the code was compiled with MSVC.
- It only ships by default on Windows 10 [or later]
Main references:
https://www.msys2.org/docs/what-is-msys2/
MSYS2 vs WSL
MSYS2 allows you to build native Windows programs, while with WSL you can only cross compile them which makes things more complicated.
https://www.msys2.org/docs/environments/ - very useful!
https://www.msys2.org/docs/who-is-using-msys2/
Git for Windows is based on MSYS2
Download and install the latest version of MSYS2.
Ensure Windows Terminal is installed. If you have Windows 11 or later, it's already installed. If you have Windows 10 or older, you'll need to manually install Windows Terminal from the Microsoft Store, here: https://apps.microsoft.com/detail/9N0DX20HK701?hl=en-zm&gl=ZM
Open Windows PowerShell and run New-Guid
7 times, one for each MSYS2 profile entry we will create below. Copy and paste the numbers out into a text editor. You'll need these numbers later. Example: here are my generated GUID numbers:
6f0ee3d1-ac4f-48ca-bcf5-a9795f9942d2
80414396-5ef4-490b-af88-29600c19ca4a
aef16ae0-7dd1-4ac7-abd8-60a646abb9ca
a718a3d5-9e77-4d0d-b7b6-69ec3d190206
1f2869c0-1310-403b-93a7-9227f42eeb24
10c96d8f-9e6b-48f6-8f59-034c586d7e57
ada1f939-0f7b-400c-b755-8cbff4fd40a8
Open Windows Terminal, and add 7 new MSYS2 profile entries:
Open Windows Terminal.
Then, click the little drop-down arrow at the top-right of the open tab, and select "Settings" --> in the Settings tab that opens up, click "Open JSON file" in the bottom-left, as shown here:
In the JSON settings file that opens up, look for the "profiles"
section in the JSON file:
"profiles":
{
"defaults": {},
"list":
[
// ...
{
"guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}",
"hidden": false,
"name": "Azure Cloud Shell",
"source": "Windows.Terminal.Azure"
}, // <=== add this comma here!
// new profile entries go here! <=====
]
},
Here, we will add 7 new MSYS2 profiles. Use a unique GUID from your previously-generated list above for each entry. Be sure to add a comma at the end of the last pre-existing profile entry above.
Here are my new entries in the JSON "profiles"
list above. Your GUIDs should be different, based on what you generated above (I actually don't know if yours need to be different from mine; I just know each entry needs a unique GUID one from another). Ensure you put a comma after each entry, including adding a comma after the ending }
of the last entry just above. Notice the Linux-like forward slashes in the paths.
My 7 new MSYS2 profiles:
"profiles":
{
"defaults": {},
"list":
[
// ============================
// previous profiles above here
// ============================
// -msys and -msys2 (same thing now: both options run msys2)
{
"commandline": "C:/msys64/msys2_shell.cmd -defterm -here -no-start -msys2 -shell bash",
"guid": "{6f0ee3d1-ac4f-48ca-bcf5-a9795f9942d2}",
"hidden": false,
"name": "MSYS2: msys2",
// "startingDirectory": "C:/msys64/home/%USERNAME%", // alternative
"startingDirectory": "%USERPROFILE%", // ie: C:\Users\my_username
"icon": "C:/msys64/msys2.ico",
"font":
{
"size": 10
}
},
// -mingw32
{
"commandline": "C:/msys64/msys2_shell.cmd -defterm -here -no-start -mingw32 -shell bash",
"guid": "{80414396-5ef4-490b-af88-29600c19ca4a}",
"hidden": false,
"name": "MSYS2: mingw32",
// "startingDirectory": "C:/msys64/home/%USERNAME%", // alternative
"startingDirectory": "%USERPROFILE%", // ie: C:\Users\my_username
"icon": "C:/msys64/mingw32.ico",
"font":
{
"size": 10
}
},
// -mingw64
{
"commandline": "C:/msys64/msys2_shell.cmd -defterm -here -no-start -mingw64 -shell bash",
"guid": "{aef16ae0-7dd1-4ac7-abd8-60a646abb9ca}",
"hidden": false,
"name": "MSYS2: mingw64",
// "startingDirectory": "C:/msys64/home/%USERNAME%", // alternative
"startingDirectory": "%USERPROFILE%", // ie: C:\Users\my_username
"icon": "C:/msys64/mingw64.ico",
"font":
{
"size": 10
}
},
// -ucrt64 (recommended default)
{
"commandline": "C:/msys64/msys2_shell.cmd -defterm -here -no-start -ucrt64 -shell bash",
"guid": "{a718a3d5-9e77-4d0d-b7b6-69ec3d190206}",
"hidden": false,
"name": "MSYS2: ucrt64 (recommended default)",
// "startingDirectory": "C:/msys64/home/%USERNAME%", // alternative
"startingDirectory": "%USERPROFILE%", // ie: C:\Users\my_username
"icon": "C:/msys64/ucrt64.ico",
"font":
{
"size": 10
}
},
// -clang64
{
"commandline": "C:/msys64/msys2_shell.cmd -defterm -here -no-start -clang64 -shell bash",
"guid": "{1f2869c0-1310-403b-93a7-9227f42eeb24}",
"hidden": false,
"name": "MSYS2: clang64",
// "startingDirectory": "C:/msys64/home/%USERNAME%", // alternative
"startingDirectory": "%USERPROFILE%", // ie: C:\Users\my_username
"icon": "C:/msys64/clang64.ico",
"font":
{
"size": 10
}
},
// -clang32
{
"commandline": "C:/msys64/msys2_shell.cmd -defterm -here -no-start -clang32 -shell bash",
"guid": "{10c96d8f-9e6b-48f6-8f59-034c586d7e57}",
"hidden": false,
"name": "MSYS2: clang32",
// "startingDirectory": "C:/msys64/home/%USERNAME%", // alternative
"startingDirectory": "%USERPROFILE%", // ie: C:\Users\my_username
"icon": "C:/msys64/clang32.ico",
"font":
{
"size": 10
}
},
// -clangarm64
{
"commandline": "C:/msys64/msys2_shell.cmd -defterm -here -no-start -clangarm64 -shell bash",
"guid": "{ada1f939-0f7b-400c-b755-8cbff4fd40a8}",
"hidden": false,
"name": "MSYS2: clangarm64",
// "startingDirectory": "C:/msys64/home/%USERNAME%", // alternative
"startingDirectory": "%USERPROFILE%", // ie: C:\Users\my_username
"icon": "C:/msys64/clangarm64.ico",
"font":
{
"size": 10
}
},
Copy and paste those 7 new profiles above into the correct location in your Windows Terminal JSON settings file.
Don't forget the comma I show with // <=== add this comma here!
above!
Save the JSON file, and close it.
How to change your default shell:
Note that if you want to use another shell, such as fish
or zsh
, you can use -shell fish
or -shell zsh
instead of -shell bash
in the profile commands above. See here: https://www.msys2.org/docs/terminals/. If you aren't sure, stick with -shell bash
.
Back in Windows Terminal, click the little drop-down arrow at the top right of your tabs at the top. You'll now see these 7 new MSYS2 entries you just added!:
Click each one to test it, and ensure they all run.
To see which terminal you are in you can run echo $MSYSTEM
in the terminal.
Example outputs:
MSYS
MINGW32
MINGW64
UCRT64
CLANG64
CLANG32
CLANGARM64
See also my answer here: How to specify in which of the 7 MSYS2 terminals to run a command in Windows from Bash, Command Prompt, & PowerShell
Choose an MSYS2 environment as your default Windows Terminal profile:
Click the little drop-down arrow to the right of the tabs at the top, and go to "Settings" again --> choose the "Startup" tab on the left.
Change the "Default profile" --> "MSYS2: ucrt64 (recommended default)".
Turn "Launch on machine startup" to "On".
Change "When Terminal starts" to "Open windows from a previous session".
Click "Save".
Here are what my Windows Terminal "Startup" settings looks like:
Change your HOME
(~
) dir from MSYS2's default of C:\msys64\home\my_username
to your regular Windows home dir of C:\Users\my_username
:
Open up C:\msys64\home\my_username\.bash_profile
in a text editor, such as VSCode. Modify it so that it looks like this. Note: you can just comment everything out with #
and add this to the top:
# Change your home (`~`) dir to `C:\Users\my_username`
HOME="/c/Users/$(whoami)"
# Source your `C:\Users\my_username\.profile` file, if it exists
if [ -f "$HOME/.profile" ]; then
. "$HOME/.profile"
fi
Close and re-open Windows Terminal. Run echo ~
and echo "$HOME"
and ensure they now both show /c/Users/my_username
. Run ls -a
and ensure you see the contents of your normal Windows home directory for your user. pwd
should show that you are currently in that directory too, since we set this via "startingDirectory": "%USERPROFILE%",
in the JSON file above.
See also my answer here: Change the location of the ~
directory in a Windows install of Git Bash
Install Ubuntu's default ~/.profile
and ~/.bashrc
files:
Now, create a C:\Users\my_username\.profile
file, if you don't already have one, and put the entire contents of this default Ubuntu ~/.profile
file into it, from my repo: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/etc/skel/.profile
If you don't have ~/.profile
file yet, the easiest way to do that is to open up your MSYS2: ucrt64 terminal and run the following:
cd ~
# download Ubuntu's default ~/.profile file
wget https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/master/etc/skel/.profile
# we might as well get the ~/.bash_logout file too
wget https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/master/etc/skel/.bash_logout
Now, go here for Ubuntu's default ~/.bashrc
file: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/etc/skel/.bashrc. Copy and paste the entire contents of this file into the top of your ~/.bashrc
file.
Put a nice # ================== END OF UBUNTU'S DEFAULT ~/.bashrc FILE ====================
marker into the end of your ~/.bashrc
file, and add any custom entries you want below that.
IMPORTANT: we do not want to remove the UCRT64
and MINGW64
type entries from our PS1
Prompt String 1 variables (which appear in the terminal before each line where you type), because we like seeing these important markers in our prompt, to remind us which MSYS2 shell we are in. So, go into your ~/.bashrc
file and comment out all changes that Ubuntu does to the PS1
variable, like this:
Change this:
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
...to this. Notice that the PS1=
changes are all commented out by doing this:
# if [ "$color_prompt" = yes ]; then
# PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
# else
# PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
# fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
# PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
Configure your PS1
prompt 1 string variable to show the git repo, branch, commit hash, and tags you are in/checked-out on:
# download this prompt string magic from my repo
curl -L https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/refs/heads/master/home/.bash_prompt_str > ~/.bash_prompt_str
# add a command to automatically source it in the bottom of your .bashrc file
echo -e "\n. ~/.bash_prompt_str" >> ~/.bashrc
References:
git submodule
“Quick Start” guideIMPORTANT: we do not want to accidentally override any really important system calls or build commands, such as make
.
Go into your ~/.bashrc
and ~/.profile
files and search for anything silly, like overriding the make
command. I had this in my ~/.bashrc
file from some earlier hacks:
alias make="'/c/Program Files/Microchip/MPLABX/v6.10/gnuBins/GnuWin32/bin/make.exe'"
Don't do that! That could mess up everything when trying to build software in your MSYS2 terminals! Delete or comment out such nonsense, like this:
# alias make="'/c/Program Files/Microchip/MPLABX/v6.10/gnuBins/GnuWin32/bin/make.exe'"
Now, close and re-open all Windows terminal windows, or run . ~/.profile
in each one to re-source your ~/.profile
file.
If you don't know what "re-sourcing" means, read my answer here: source
(.
) vs export
(and also some file lock [flock
] stuff at the end).
Run alias
to see all of your aliases. Look for any silly aliases you don't want, and delete or comment them out from your ~/.bashrc
or ~/.profile
files if necessary. Again, I had a ridiculous make
alias (see above) ruining everything!
Also run echo "$PATH"
to look for any silliness in your PATH that shouldn't be there. If you haven't been modifying your PATH before, it should be fine.
Test your new, beautiful Ubuntu settings: run ll
and you'll see this alias now works! It is an alias for ls -alF
, and comes from your ~/.bashrc
file now.
Update MSYS2:
# Upgrade all packages; whenever it asks you to continue, just press
# Enter to say yes. This could take a long time (tens of minutes) if
# you haven't updated in a while.
pacman -Suy
# Run it again to make sure everything is up to date. Keep running it
# again and again until it finally says `there is nothing to do` on the
# last line.
References:
man pacman
; online here: https://man.archlinux.org/man/pacman.8.enInstall the GCC compiler and other build and test tools into the MSYS2 UCRT64 environment:
# Install the GCC compiler
pacman -S mingw-w64-ucrt-x86_64-gcc
# Press Enter or type Y then Enter to continue
# Check the gcc version to ensure it installed correctly
# Example output: `gcc.exe (Rev2, Built by MSYS2 project) 13.2.0`
gcc --version
# Install ccache
pacman -S mingw-w64-ucrt-x86_64-ccache
# Check your ccache version to ensure it installed successfully
# - I have `ccache version 4.10.2`
ccache --version
# Install gtest
# - As it installs, pay attention to what version it gave you. Mine shows
# 1.15.2-1:
#
# Packages (1) mingw-w64-ucrt-x86_64-gtest-1.15.2-1
#
pacman -S mingw-w64-ucrt-x86_64-gtest
References:
Install VSCode and add the code
executable into your PATH:
Install VSCode from here, if you don't already have it: https://code.visualstudio.com/
The code
executable is found in the "$HOME/AppData/Local/Programs/Microsoft VS Code/bin"
dir.
Add it to your PATH by adding this line to the bottom of your ~/.bashrc
file:
DIR="$HOME/AppData/Local/Programs/Microsoft VS Code/bin"
if [ -d "$DIR" ] ; then
PATH="$DIR:$PATH"
fi
Close and re-open all terminals, or run . ~/.profile
in each one to re-source your ~/.profile
and ~/.bashrc
files.
Now run code .
in a terminal and it will open up a new instance of VSCode in your current directory. Now we're rockin'.
Install and configure git:
This is beyond the scope of this answer, but oddly enough, MSYS2 currently recommends you install and use Git For Windows and Git Bash (based on MSYS2) instead of trying to install git within MSYS2: https://www.msys2.org/docs/git/
So, here are some links to resources I've created to help you install Git for Windows / Git Bash:
At a minimum: install Git for Windows. Then, add one of these lines to the bottom of your ~/.bashrc
file to give your MSYS2 environments the most basic of git
usage and access:
# If git was installed locally, use this alias:
alias git="$HOME/AppData/Local/Programs/Git/bin/git.exe"
# If git was installed globally, use this alias instead:
alias git='"/c/Program Files/Git/bin/git.exe"'
Close and re-open all terminals, or run . ~/.profile
to re-source your ~/.profile
and ~/.bashrc
files, and your MSYS2 environments can now run this:
git --version
# I see: `git version 2.42.0.windows.2`
Now that you have MSYS2 installed and working, your Windows computer is much more useful and functional!
But, since you can't easily install git into MSYS2, you may still want to use separate terminals: MSYS2 terminals for building with gcc
/g++
and testing with gtest
, and the Git Bash terminal for git
operations.
What a pain Windows is. Just wipe it and install Linux Ubuntu. Linux Ubuntu is the only OS installed on most of my computers, including for my kids. :)
To install build tools in the other MSYS2 terminals, see my answer here, where I show the install commands for gcc
or clang
, cmake
, and make
, for instance, in each terminal: Detecting your build platform/environment in C and C++ at compile-time in Linux, Windows, GCC, MSYS2, Cygwin, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With