The problem is that if you try to support Linux/MaxOS with POSIX Shells and Windows you quickly find there is no easy solution that allows your project to build in both without changing the command in the pre-build.
MPLAB simply does the equivalent of system("your command string here") and you are on your own for what happens next.
If you are on a system with POSIX Shells (aka Linux or MacOS) you need to enter something that will run correctly by /bin/sh. I.e. the first thing in the string needs to be either a command (i.e. something found somewhere in $PATH, or a path. The path can be absolute or relative, but it must contain at least one slash ("/"). So either /somewhere/somedir/myscript or ../somewhere/myscript or ./myscript.
If you are on Windows, then again a command found in the $path works. An absolute path works, but only with back slashes ("\"). And if you want to run something out of the local directory (projectname.X for mplab project) you just use the script name. No self relative path name allowed.
So how do you support a project that needs to run without change in both environments? mplabs doesn't help. A quick suggestion would for it to have two script options. One of POSIX systems and one for Windows. But it doesn't...
I found that on Linux (presumably MacOS as well) using sh to run the script worked:
sh -c "./youscripthere your args here"But how to make that work in Windows?
Solution, a simple program we'll call fakesh. A half dozen lines of .c to look for the argument after -c, strip the "./" and call system() with that:
system("youscripthere your args here")This works because the first call to system invokes sh.exe (which we put in the project directory.)
The second call to system calls "yourscripthere.bat" which also resides in the project directory.
We end up with the following in the project directory:
- sh.exe - the fakesh binary
- yourscripthere - posix shell script
- yourscripthere.bat - Windows bat file
For the USBLAN Demo project I use this to generate a confname.h file containing the project name, project dir, device name etc, before creating the new web_pages_img.c file.
And it does work well, for both Linux and Windows, without change. :-)
Fakesh.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void usage(const char * msg) {
fprintf(stderr, "Usage: sh -c 'args'\r\n");
fprintf(stderr, "%s\r\n", msg);
exit(1);
}
int main(int argc, char *argv[]) {
char *cp;
cp = argv[2];
if (strncmp(cp, "./", 2) == 0) cp += 2;
system(cp);
}