Microchip MPLAB X IDE: configure and run a shared pre-build-step Bash script that runs in both Windows and Linux as part of the build process

Our team has a mix of developers on both Windows and Linux, and a shared code base that has to be able to compile on both, in the Microchip MPLAB X IDE v6.20, for PIC32 microcontrollers in our case.

I see in the project properties (right-click the project name –> Properties) there is an option for adding a pre-build step, here:

enter image description here

This could be used for auto-generating C code .h header files, for instance. How can we get a common pre-build script here to run on both Windows and Linux in the MPLAB X IDE?

I’m having a lot of challenges because the bash commands available in the MPLAB X IDE are inconsistent and have missing options and commands.

After much effort, I figured it out. The best (most versatile) way to do it is to use a common .sh bash script which will run on both Linux and Windows. This bash script can then do whatever pre-build steps you want. It could call other executables, other bash scripts, Python scripts, or just do the work directly.

How to configure a preBuildSteps.sh Bash script that runs as part of the pre-build process in the MPLAB X IDE on both Windows and Linux

Add this line into that "Execute this line before build" box, on both Windows and Linux:

"C:Program FilesGitgit-bash.exe" ../preBuildSteps.sh && echo "Pre-build output logged to 'autogenerated/logs/'"

This assumes that:

  1. You have the Git Bash terminal installed in Windows and it is located at Windows path "C:Program FilesGitgit-bash.exe".
  2. You have a bash script called preBuildSteps.sh one level up from the *.X MPLAB X project directory. So, relative to the *.X project directory, it is located at ../preBuildSteps.sh.
  3. You’d like to log your pre-build output to autogenerated/logs/ in the root of your project.

On Windows, install Git for Windows, which contains the Git Bash terminal. I recommend you follow my instructions here: Installing Git For Windows.

On Linux, create an executable symlink to bash, with a symlink filename of C:Program FilesGitgit-bash.exe (this is a legal filename in Linux), and place it into your ~/bin directory, as follows:

# Ensure this directory exists 
mkdir -p ~/bin

# Now create the symlink
ln -si $(which bash) ~/bin/"C:Program FilesGitgit-bash.exe"

Now, ensure that ~/bin is in your PATH. If on Linux Ubuntu, the following should already be in the bottom of your ~/.profile file:

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

If it’s not, then add that to the bottom of your ~/.profile file (preferred) or ~/.bashrc file and then re-source (import) it by running:

. ~/.profile
. ~/.bashrc

Now, you should be able to run 'C:Program FilesGitgit-bash.exe' as an executable alias to bash from your Linux terminal. Test it by running the following, and you should see the exact same output from each:

# Check your Linux bash version
bash --version

# Also check the exact same Linux bash version
'C:Program FilesGitgit-bash.exe' --version

Now, create a bash script called preBuildSteps.sh in the root of your project, and place your pre-build steps into it. Here is a very thorough example of what it might look like:

myProject/preBuildSteps.sh:

#!/usr/bin/env bash

# This script contains pre-build steps to run at the start of the build in 
# MPLAB X IDE. 

# Get paths. See my answer: /a/60157372/4561887
FULL_PATH_TO_SCRIPT="$(realpath "${BASH_SOURCE[-1]}")"
SCRIPT_DIRECTORY="$(dirname "$FULL_PATH_TO_SCRIPT")"
SCRIPT_FILENAME="$(basename "$FULL_PATH_TO_SCRIPT")"
LOG_DIR="$SCRIPT_DIRECTORY/autogenerated/logs"
LOG_FILE="$LOG_DIR/$SCRIPT_FILENAME.log"

mkdir -p "$LOG_DIR"
# Change to the script's directory so all relative paths work correctly.
# From this point on, all paths below can be relative to the script's directory.
cd "$SCRIPT_DIRECTORY"  

# Function to print a separator in the terminal between commands.
print_separator() {
    printf "n====================nn"
}

# start of output log; see: https://serverfault.com/a/103509/357116
((

echo -e "nRunning $SCRIPT_FILENAME..."
echo "Logging output to "$LOG_FILE"." 

print_separator

# ------------------------- START OF PRE-BUILD STEPS ---------------------

# Run these prebuild scripts you may have

# Autogenerate at header file at:
# 1. autogenerated/autogenerated/MyAutogeneratedHeader1.h
# 2. autogenerated/autogenerated/MyAutogeneratedHeader2.h
# 3. autogenerated/autogenerated/MyAutogeneratedHeader3.h
./autogenerated/scripts/make_MyAutogeneratedHeader1.h.sh;    print_separator
./autogenerated/scripts/make_MyAutogeneratedHeader2.h.sh;    print_separator
./autogenerated/scripts/make_MyAutogeneratedHeader3.h.sh;    print_separator

# Now handle running a **Windows** binary executable on Linux, by running it
# with `wine`. 
# See my answer: /a/78480875/4561887
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
    # OS is Linux, so use wine to run the Windows executable.
    wine ./autogenerated/bin/myWindowsExecutable.exe arg1 arg2 arg3
elif [[ "$OSTYPE" == "msys" ]]; then 
    # OS is Windows (Git Bash), so run the Windows executable directly.
    ./autogenerated/bin/myWindowsExecutable.exe arg1 arg2 arg3
fi
print_separator

# ------------------------- END OF PRE-BUILD STEPS -----------------------

# end of output log
) 2>&1) | tee "$LOG_FILE"

Lastly, you should ignore your autogenerated files and logs via your .gitignore file. Assuming you have this project structure (as shown by tree -a):

myProject
├── autogenerated
│   ├── autogenerated
│   │   ├── MyAutogeneratedHeader1.h
│   │   ├── MyAutogeneratedHeader2.h
│   │   └── MyAutogeneratedHeader3.h
│   ├── bin
│   │   └── myWindowsExecutable.exe
│   ├── .gitignore
│   ├── logs
│   │   └── preBuildSteps.sh.log
│   ├── README.md
│   └── scripts
│       ├── make_MyAutogeneratedHeader1.h.sh
│       ├── make_MyAutogeneratedHeader1.h.sh
│       └── make_MyAutogeneratedHeader1.h.sh
├── myProject.X
│   └── ...project configuration files and build output...
├── ...other project files...

…then here is an example of what your myProject/autogenerated/.gitignore file shown above might look like to ignore all autogenerated files and logs, except for a README.md file in each directory, if one exists:

myProject/autogenerated/.gitignore:

# Ignore all files herein; see: /a/67551691/4561887
/autogenerated/*
# Except this file if it exists
!/autogenerated/README.md

# Ignore all files herein
/logs/*
# Except this file if it exists
!/logs/README.md

That’s it! Now, when you build your project in MPLAB X, it will run the prebuild command of:

"C:Program FilesGitgit-bash.exe" ../preBuildSteps.sh && echo "Pre-build output logged to 'autogenerated/logs/'"

On Windows, this opens a Git Bash terminal via "C:Program FilesGitgit-bash.exe", and then runs your ../preBuildSteps.sh Bash script within it. At the end, it prints Pre-build output logged to 'autogenerated/logs/' so that you can see that inside your MPLAB X IDE build output window. This is helpful because the Git Bash popup window terminal will have just closed and you’ll have missed all the output it printed, so you need a way to review the output in the log file.

On Linux, you have a magical symlink to bash, in your PATH at ~/bin/"C:Program FilesGitgit-bash.exe", so it simply runs the ../preBuildSteps.sh Bash script directly inside of a new bash sub-shell, and then of course also prints Pre-build output logged to 'autogenerated/logs/' at the end.

The preBuildSteps.sh script does whatever you want it to do. In my example above, I have it call other scripts to autogenerate some C header files, and I have it handle a unique case where it needs to run a Windows executable on Linux through wine. I make it log all output to autogenerated/logs/preBuildSteps.sh.log, which gets ignored by your .gitignore file shown in the project tree above.

Additional notes

An alternative to creating the bash symlink on Linux via ln -si $(which bash) ~/bin/"C:Program FilesGitgit-bash.exe" is to create a bash wrapper script instead. Such a script would still be located at path ~/bin/"C:Program FilesGitgit-bash.exe", but it would contain the following contents:

#!/usr/bin/env bash

# This is a wrapper to simulate Windows's Git Bash terminal in Linux

bash "$@"

It could be created by running these commands:

# Create the file (copy and paste this whole chunk into your terminal all 
# at once, from here to the `echo` line below)
file_contents=$(cat << 'EOF'
#!/usr/bin/env bash

# This is a wrapper to simulate Windows's Git Bash terminal in Linux

bash "$@"
EOF
)
echo "$file_contents" > ~/bin/"C:Program FilesGitgit-bash.exe"


# Make the file executable
chmod +x ~/bin/"C:Program FilesGitgit-bash.exe"

The end result would be the exact same as using the symlink to bash, but the symlink is easier. The wrapper script would be better if you need to have it do additional things before running bash.

Handling multiple build configurations with one ../preBuildSteps.sh script

If you have multiple build configurations in MPLAB X, rather than creating a separate ../preBuildSteps.sh script for each one, you can simply pass in the build configuration name as an argument to the script, and then have the script do different things based on the build configuration name. For example, add this to your ../preBuildSteps.sh script:

# ------------------------- START OF PRE-BUILD STEPS ---------------------

# Do common build configuration stuff here
# ...

# Do build configuration-specific stuff here
if [[ "$1" == "--myBuildConfiguration1" ]]; then
    # Do unique stuff for Build Configuration 1
elif [[ "$1" == "--myBuildConfiguration2" ]]; then
    # Do unique stuff for Build Configuration 2
elif [[ "$1" == "--myBuildConfiguration3" ]]; then
    # Do unique stuff for Build Configuration 3
fi

# ------------------------- END OF PRE-BUILD STEPS -----------------------

References and additional resources

  1. The only chars forbidden in Linux filenames are / (forward slash) and (null char, or binary zero). See:
    1. What characters are forbidden in Windows and Linux directory names?
    2. Are there any invalid linux filenames?
    3. Wikipedia: Filename.
  2. My instructions to install the Git Bash terminal in Windows: Installing Git For Windows.
  3. My bug report: VSCode cannot open files with backslashes in their names on Linux: Cannot open or edit valid files on Linux with backslashes in names; example of a text filename on Linux: C:Program FilesGitgit-bash.exe
  4. My answer: How do I get the directory where a Bash script is located from within the script itself?
  5. Server Fault: How can I fully log all bash scripts actions?
  6. My answer: How to detect the OS from a Bash script?
  7. My answer: How to UNignore some select contents (files or folders) within an ignored folder
  8. MPLAB X IDE XC32 compiler and license issues:
    1. My answer: How to renew your paid Microchip XC32 Compiler Pro license when it has expired or is about to expire
    2. My answer: How do I make my Microchip MPLAB X IDE project use the free version of the XC32 compiler?
    3. My project to build a license-free version of the compiler yourself on both Linux and Windows: https://github.com/ElectricRCAircraftGuy/Microchip_XC32_Compiler

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật