22

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"
}
5
  • 1
    When you run msys outside of the Terminal, what's the path to the compiler? Is that directory still on the PATH when you run inside of the Windows Terminal? You may want to refer to this doc which has some subtle differences between git bash and msys2 Commented Feb 17, 2022 at 20:38
  • The path is the same one for the download C:\msys64\... Commented Feb 18, 2022 at 9:43
  • 1
    Related: SuperUser: Change default shell on MSYS2 Commented Oct 31, 2023 at 20:27
  • bash has nothing to do at all with compiling C/C++ code. It sounds like you're trying to bring over a specific workflow linux to windows that is only incidental to the actual objective of building C++. Commented Jul 18 at 18:26
  • There's an explanation of the command line arguments Commented Nov 15 at 16:21

3 Answers 3

40

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.

Installing & setting up MSYS2 from scratch, including adding all 7 profiles to Windows Terminal...

...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:

  1. From Git Bash, you can run git commands in native Windows.
  2. From the MSYS2 UCRT64 (or similar) terminal, you can run gcc build commands in native Windows. Ex: like this from my eRCaGuy_hello_world repo: https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/c/hello_world_extra_basic.c#L24:
    gcc -Wall -Wextra -Werror -O3 -std=gnu17 hello_world_extra_basic.c -o bin/a -lm && bin/a
    
  3. From WSL (Windows Subsystem for Linux), you can have a true Linux environment within Windows. The previous two are Linux-like environments in Windows. WSL is truly Linux within Windows.

Description of all 7 MSYS2 profiles to add to Windows Terminal

Here are the 7 MSYS2 shell/environment types:

  1. 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).
  2. mingw32 - Minimalist GNU for Windows 32-bit; contains GCC 32-bit compiler
  3. mingw64 - Minimalist GNU for Windows 64-bit; contains GCC 64-bit compiler
  4. ucrt64 - 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.
  5. clang64 - contains the LLVM/Clang 64-bit compiler
  6. clang32 - contains the LLVM/Clang 32-bit compiler
  7. clangarm64 - contains the LLVM/Clang 64-bit ARM (AArch64) compiler

From: https://www.msys2.org/docs/environments/:

enter image description here

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. Setting MSYSTEM to UCRT64 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:

  1. 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.

  2. https://www.msys2.org/docs/environments/ - very useful!

  3. https://www.msys2.org/docs/who-is-using-msys2/

    Git for Windows is based on MSYS2

Setting up all 7 MSYS2 shells/environments to run in Windows Terminal

  1. Download and install the latest version of MSYS2.

    1. You can get it here: https://www.msys2.org/.
  2. 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

  3. 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
    
  4. 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:

    enter image description 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.

  5. 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.

  6. 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!:

    enter image description here

  7. 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

  8. 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:

    enter image description here

  9. 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

  10. 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.

  11. 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
    
  12. 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:

    1. My article on my personal website: git submodule “Quick Start” guide
    2. ...and in my repo: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/README_git_submodules.md
  13. IMPORTANT: 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'"
    
  14. 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.

  15. 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.

  16. 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:

    1. https://www.msys2.org/docs/updating/
    2. man pacman; online here: https://man.archlinux.org/man/pacman.8.en
    3. My own experimentation
  17. Install 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:

    1. I learned this from the "Getting Started" content right on the home page of the MSYS2 project, here: https://www.msys2.org/.
    2. Chats with GitHub Copilot, and personal experimentation
    3. My Q&A: How do I build and use googletest (gtest) and googlemock (gmock) with gcc/g++ or clang?
  18. 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'.

  19. 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:

    1. Installing Git For Windows: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/issues/27#issue-1950880578
    2. Adding Git-Bash to the new Windows Terminal
    3. Running SSH Agent when starting Git Bash on Windows
    4. Python not working in the command line of 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`
    
  20. 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.

Continue reading in Part 2 of 2...

Sign up to request clarification or add additional context in comments.

6 Comments

This should have been marked as accepted answer. Thanks for these detailed instructions!
And add you minimal git branch to your PS1 using this answer.
Thanks for this extensive post. However, it was nearly impossible to get the PATH to get included. It seem that MSYS are doing something with the quotations, so when my git is a Program Files you can't use " nor \<space>. Instead only the following worked: DIR="/c/Program Files/Git/cmd". In addition, forget all the confusing profile files. Just add that close the to top of your .bashrc, just after the interactive check.
this is wonderful! THANK YOU FOR SHARING!!!!!
Just installed MSYS2 from scratch again, and there are only 6 *.ico files in c:/msys64 now; more specifically clang32.ico has been removed, and the -clang32 entry as given here does not seem to work anymore.
|
12

I would recommend checking the docs for that but here is my own MSYS edit

{
    "commandline": "C:\\msys64\\msys2_shell.cmd -defterm -here -no-start -mingw64 -shell bash",
    "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
    "hidden": false,
    "name": "msys2"
}

Use New-Guid in powershell to create a new guid

Comments

3

Part 2 of 2. (I had to split this answer into two parts because it's too long, > 30k characters).

Jump to Part 1 of 2.

Installing & setting up MSYS2 from scratch, including adding all 7 profiles to Windows Terminal...

...so you can build native Windows applications with gcc on Windows.

Building with gcc via the MSYS2 UCRT64 or other MSYS2 environments inside the Git Bash terminal

Since your custom MSYS2 terminals don't properly run git, and the Git for Windows Git Bash terminal doesn't properly run gcc, my recommendation is that you use the Git Bash terminal for everything.

To get gcc to run inside of it, we will use a custom msys2_terminal wrapper function from my answer here: How to specify in which of the 7 MSYS2 terminals to run a command in Windows from Bash, Command Prompt, & PowerShell. See the section of this answer titled "Final answer: a better Bash wrapper function to rule them all!"

So, go to that answer and copy my entire msys2_terminal function definition and the alias ucrt64="msys2_terminal ucrt64" convenience alias underneath it into your ~/.bashrc file. Then, close and re-open all terminals, or call . ~/.bashrc within each one, to cause them to re-source this file.

Usage: you can now run the msys2_terminal wrapper function from within Git Bash or any other MSYS2 terminal to run a command in any of the 7 MSYS2 environments:

# General usage:
msys2_terminal <terminal> <command> [<args>...]
 
# Example: show which terminal is running this command
# Example output: UCRT64
msys2_terminal ucrt64 echo '$MSYSTEM'

Now, inside the Git Bash terminal, you have access to gcc from the UCRT64 terminal!

Example run and output, showing that gcc is available from the UCRT64 terminal while you are operating inside the Git Bash or any other MSYS2 terminal:

$ msys2_terminal ucrt64 gcc --version
--Running in MSYS2 ucrt64 terminal...START--
gcc.exe (Rev2, Built by MSYS2 project) 14.2.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

--Running in MSYS2 ucrt64 terminal...END--

Or, even easier, using the ucrt64 alias, simply call:

ucrt64 gcc --version

Pretty cool, huh? You now can use the Git Bash terminal for everything, including building and running and testing with the gcc compiler and other tools!

How to package a "portable" MSYS2-built Windows application with all required DLLs to run in any Windows environment or terminal

See my answer here.

For a full demo of creating a portable application with included DLLs from MSYS2 on Windows, see my repo here: https://github.com/ElectricRCAircraftGuy/eRCaGuy_Linux_Windows_CMake_Sockets_MSYS2.

CMake

Tested on Windows 11 in the UCRT64 terminal.

For a full demo of CMake in MSYS on Windows, see my repo here: https://github.com/ElectricRCAircraftGuy/eRCaGuy_Linux_Windows_CMake_Sockets_MSYS2.

Install CMake, build, and run

# Install cmake into the UCRT64 terminal
pacman -S mingw-w64-ucrt-x86_64-cmake

# Build with CMake

mkdir -p build
# clean the build directory in case it already existed and had stuff in it
rm -rf build/*
cd build
cmake ..  # Configure the project from all CMakeLists.txt and *.cmake files
# Build: works on any OS; uses Make on Linux and Ninja on Windows
time cmake --build . --parallel "$(nproc)"
# OR: for Linux only, the above command is equivalent to: 
time make -j "$(nproc)"

# Run the program
./my_program.exe

Typical workflow

# First time setup
mkdir build
cd build
cmake ..                                # Configure the project
cmake --build . --parallel "$(nproc)"   # Build the project

# After changing source code only
cmake --build . --parallel "$(nproc)"   # Just rebuild

# After changing CMakeLists.txt or any *.cmake files
cmake ..                                # Reconfigure
cmake --build . --parallel "$(nproc)"   # Then rebuild

References

  1. CMake tutorial: https://cmake.org/cmake/help/latest/guide/tutorial/index.html
  2. Official documentation on all CMake commands: https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html

pacman -S package manager issues in MSYS2

  1. When running pacman -Syu, or any other pacman installation command, if you get a lot of Operation too slow. Less than 1 bytes/sec transferred the last 10 seconds errors--Example:

    error: failed retrieving file 'libopenssl-3.5.1-1-x86_64.pkg.tar.zst' from repo.msys2.org : Operation too slow. Less than 1 bytes/sec transferred the last 10 seconds

    ...then add the --disable-download-timeout option like this:

    pacman -Syu --disable-download-timeout
    

    See:

    1. The original source: https://github.com/msys2/MSYS2-packages/issues/1658#issuecomment-495955432
    2. Where I added this information into this other person's answer too: Certificate error when trying to install MSYS2 packages on Windows server
  2. Error: SSL certificate problem: unable to get local issuer certificate:

    If you get this error when running pacman -Syu or pacman -S gest or any other pacman installation command, then follow these instructions here: Certificate error when trying to install MSYS2 packages on Windows server.

    The above error may occur when your Windows 11 computer is managed by work/IT and has, for instance, ZScaler installed.

    See also my comment here, under the answer just above.

Sockets

For Linux and Posix sockets (Ethernet/IP packets, UDP/TCP) in Windows, use the msys2 terminal, since it has cygwin as its C library and supports Unix/Linux sockets on Windows.

For a full demo of building and running Unix sockets in MSYS on Windows, see my repo here: https://github.com/ElectricRCAircraftGuy/eRCaGuy_Linux_Windows_CMake_Sockets_MSYS2.

Tested on Windows 11 in the base msys2 terminal.

  1. Use the base msys2 terminal, which has Posix compatibility apparently, including support for Unix/Linux sockets, not the ucrt64 terminal.

  2. Install gcc and ccache:

    # Update the package database and core system packages; run repeatedly
    # until no more updates are available
    pacman -Suy  
    
    # Run once each to install gcc and ccache into the msys2 environment
    pacman -S gcc
    pacman -S ccache
    # (optional, but recommended): install cmake, make, gdb, and gtest too
    pacman -S cmake
    pacman -S make
    pacman -S gdb
    pacman -S gtest
    
  3. Now you can build and run Linux Posix socket code in Windows!

    Example: get these two files from my eRCaGuy_hello_world repo, and build and run them:

    # Option 1 (recommended): clone the repo
    git clone https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world.git
    cd eRCaGuy_hello_world/c
    
    # OR: Option 2: get the files directly
    # Get the server file
    wget https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/refs/heads/master/c/socket__geeksforgeeks_udp_server_GS_edit_GREAT.c
    # Get the client file
    wget https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/refs/heads/master/c/socket__geeksforgeeks_udp_client_GS_edit_GREAT.c
    
    # Then: 
    
    # Mark both as executable (required on Linux or Unix but not on Windows)
    chmod +x socket__geeksforgeeks_udp_server_GS_edit_GREAT.c
    chmod +x socket__geeksforgeeks_udp_client_GS_edit_GREAT.c
    
    # Build and run the server file
    ./socket__geeksforgeeks_udp_server_GS_edit_GREAT.c
    
    # IN A SEPARATE MSYS2 terminal, build and run the client file
    ./socket__geeksforgeeks_udp_client_GS_edit_GREAT.c
    

    Example build, run, and output:

    1. In the first terminal, building and running the UDP server
      eRCaGuy_hello_world/c/temp
      $ ./socket__geeksforgeeks_udp_server_GS_edit_GREAT.c
      STARTING UDP SERVER:
      1. Create a socket object, obtain a file descriptor to it, and prepare server and client `struct sockaddr_in` internet namespace ("in") socket addresses.
      2. Bind the socket object with the server address specified above so that it can be used.
      3. Block until a message is received.
      4. Process the received message, & print out address info. of the sender, followed by the message!
      Sender (client) address information:
        socket internet namespace (sin) address family name = AF_INET (IPv4 address)
        port                                                = 60063
        IP address                                          = 127.0.0.1
      Msg received from sender (client) (19 bytes):
        Hello from client.
      5. Send a response back to the sender of the message we just received.
      Done! This msg was just sent to the client:
        Hello from server.
      
    2. In the second terminal, building and running the UDP client
      eRCaGuy_hello_world/c
      $ ./socket__geeksforgeeks_udp_client_GS_edit_GREAT.c
      STARTING UDP CLIENT:
      1. Create a socket object and obtain a file descriptor to it.
      2. Send a message to the server.
      Done! This msg was just sent to the server:
        Hello from client.
      3. Block until a message is received.
      4. Process the received message, & print out address info. of the sender, followed by the message!
      Sender (server) address information:
        socket internet namespace (sin) family name = AF_INET (IPv4 address)
        port                                        = 20000
        IP address                                  = 127.0.0.1
      Msg received from sender (server) (19 bytes):
        Hello from server.
      

Additional MSYS2 configuration notes

The answer by @Weed Cookie helped me. It shows me how to use PowerShell to generate GUIDs, and how to specify the shell with -shall bash.

This MSYS2 documentation was the most useful: https://www.msys2.org/docs/terminals/. It showed me how to specify the commandline, icon, font, starting directory, and "shell type" with -ucrt64, -msys2, etc.

There are 3 places I am aware of to see that all of these 7 MSYS2 environments exist. This was not easy for me to track down. Here they are:

  1. [The most definitive, perhaps] Open up the "C:\msys64\msys2_shell.cmd" Windows batch file in a text editor, and look for these lines:

    rem Shell types
    if "x%~1" == "x-msys" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MSYS& goto :checkparams
    if "x%~1" == "x-msys2" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MSYS& goto :checkparams
    if "x%~1" == "x-mingw32" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MINGW32& goto :checkparams
    if "x%~1" == "x-mingw64" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MINGW64& goto :checkparams
    if "x%~1" == "x-ucrt64" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=UCRT64& goto :checkparams
    if "x%~1" == "x-clang64" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=CLANG64& goto :checkparams
    if "x%~1" == "x-clang32" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=CLANG32& goto :checkparams
    if "x%~1" == "x-clangarm64" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=CLANGARM64& goto :checkparams
    if "x%~1" == "x-mingw" shift& set /a msys2_shiftCounter+=1& (if exist "%WD%..\..\mingw64" (set MSYSTEM=MINGW64) else (set MSYSTEM=MINGW32))& goto :checkparams
    

    In those lines, we see the 7 shell types listed above. You can see that x-msys and x-msys2 are the same thing, because they both call set MSYSTEM=MSYS. x-mingw is a special case, because it checks for the existence of the mingw64 directory, and if it exists, it sets MSYSTEM=MINGW64; otherwise it sets MSYSTEM=MINGW32.

    If you check the help menu for this batch file by running C:\msys64\msys2_shell.cmd --help in a Command Prompt, you'll see the following:

    C:\>.\msys64\msys2_shell.cmd --help
    Usage:
        msys2_shell.cmd [options] [login shell parameters]
    
    Options:
        -mingw32 | -mingw64 | -ucrt64 | -clang64 | -msys[2]   Set shell type
        -defterm | -mintty | -conemu                            Set terminal type
        -here                            Use current directory as working
                                        directory
        -where DIRECTORY                 Use specified DIRECTORY as working
                                        directory
        -[use-]full-path                 Use full current PATH variable
                                        instead of trimming to minimal
        -no-start                        Do not use "start" command and
                                        return login shell resulting
                                        errorcode as this batch file
                                        resulting errorcode
        -shell SHELL                     Set login shell
        -help | --help | -? | /?         Display this help and exit
    
    Any parameter that cannot be treated as valid option and all
    following parameters are passed as login shell command parameters.
    

    Notice that the "shell type" options are -mingw32, -mingw64, -ucrt64, -clang64, -msys[2]. The -msys[2] part means that you can use either -msys or -msys2 to specify the MSYS2 shell type. But, they are missing two of the types!: -clang32 and -clangarm64! So, the only way to see those is to look inside the C:\msys64\msys2_shell.cmd batch file itself, rather than looking at its help menu.

    If you look inside C:\Users\my_username\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\MSYS2, you'll see these 6 start menu entries:

    'MSYS2 CLANG64.lnk'
    'MSYS2 CLANGARM64.lnk'
    'MSYS2 MINGW32.lnk'
    'MSYS2 MINGW64.lnk'
    'MSYS2 MSYS.lnk'
    'MSYS2 UCRT64.lnk'
    

    Again, they are missing one!--this time: clang32.

  2. You can see all 7 .exe executables here: C:\msys64.

    Here is what that looks like from the MSYS2: ucrt64 command line. You can see all 7 here:

    ls -1 /c/msys64/*.exe
    

    Output:

    /c/msys64/clang32.exe
    /c/msys64/clang64.exe
    /c/msys64/clangarm64.exe
    /c/msys64/mingw32.exe
    /c/msys64/mingw64.exe
    /c/msys64/msys2.exe
    /c/msys64/ucrt64.exe
    /c/msys64/uninstall.exe
    
  3. You can also look online and see all 7 in the table here: https://www.msys2.org/docs/environments/:

    enter image description here

Other references

  1. What is the alternative for ~ (user's home directory) on Windows command prompt? - answer: %USERPROFILE% or %HOMEDRIVE%%HOMEPATH% (see my comment)
  2. Oddly enough: even though Git Bash is based on MSYS2, you can't easily install git into MSYS2. MSYS2 actually recommends you install Git for Windows and use Git Bash: https://www.msys2.org/docs/git/

TODO

  1. [ ] Add chocolatey/ripgrep (/c/ProgramData/chocolatey/bin) bin dir to MSYS PATH. This will give me access to rg.
  2. [ ] Add meld (/c/Program Files/Meld/meld) to MSYS PATH.

See also

  1. My answer where I show how to install build tools in the other MSYS2 terminals. 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.

  2. My repo here: https://github.com/ElectricRCAircraftGuy/eRCaGuy_Linux_Windows_CMake_Sockets_MSYS2

  3. My answer: How to specify in which of the 7 MSYS2 terminals to run a command in Windows from Bash, Command Prompt, & PowerShell Contains my msys2_terminal wrapper function and ucrt64 alias.

  4. My answer: How to package a "portable" MSYS2-built Windows application with all required DLLs to run in any Windows environment or terminal

  5. Other answers of mine where I've referenced or quoted this answer:

    1. How to change HOME directory and start directory on MSYS2?
    2. Super User: How can I change my MinGW/MSYS + mintty home directory?
    3. Super User: MinGW Bash profile
    4. The VSCode code . command is not working in the terminal/command prompt in Windows
    5. Super User: Change default shell on MSYS2
  6. More guidance on which of the seven MSYS2 environments to choose: https://github.com/msys2/MINGW-packages/issues/6711#issuecomment-1799881712

  7. My answer: How to detect the OS from a Bash script?

Return to Part 1 of 2...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.