Last active
August 6, 2019 12:08
-
-
Save garettbass/ae8b458577c54a4993996eed1687688d to your computer and use it in GitHub Desktop.
Self-executable C++ file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///usr/bin/env \ | |
[ -n "${PATHEXT}" ] && ext='.exe'; \ | |
bin="$(dirname $0)/$(basename ${0%.*})$ext"; \ | |
c++ -std=c++11 -Werror -o $bin $0 \ | |
&& $bin "$@"; \ | |
status=$?; \ | |
rm $bin; \ | |
exit $status | |
#include <cstdio> | |
int main(int argc, char** argv) { | |
for (int i = 0; i < argc; ++i) { | |
printf("argv[%i]: \"%s\"\n",i,argv[i]); | |
} | |
return 0; | |
} |
I updated the header to determine the correct file extension for the executable, .exe
for windows (where the environment should have $PATHEXT
), and no extension for Unix-like environments.
Here is an overview of each line of the header:
///usr/bin/env \
- This line is similar to a shebang,
#!/user/bin/env
, that you might find in a shell, python, ruby, etc. script, and ends with a line continuation,\
, so that the next few lines can combine into one long shell command. The shell interprets///
the same as a single slash, and the C/C++ compiler interprets the first two slashes as a single-line comment. The line continuations at the end of each line of the header enable that single line comment to extend over multiple lines, making the various stages of the script more readable than they would be on a single long line.
[ -n "${PATHEXT}" ] && ext='.exe'; \
- This line checks whether the
$PATHEXT
environment variable is non-empty, and if so sets theext
variable to contain the string'.exe'
. The$PATHEXT
environment variable is generally only present on Windows systems, to my knowledge, and is used as a convenient check that we need to compile an executable ending with the.exe
file extension.
bin="$(dirname $0)/$(basename ${0%.*})$ext"; \
- This sets the variable
bin
to contain a directory-qualified path to the compiled executable. The rest of the command will use$bin
to refer to the compiled executable.
c++ -std=c++11 -Werror -o $bin $0 \
- This line invokes the C++ compiler to compile
$0
, the input file, to produce the executable$bin
. You can customize the compiler invocation as needed. I generally add include directories and such on additional lines with line continuations. To compile C instead, change this line to:cc -std=c11 -Werror -o $bin $0 \
&& $bin "$@"; \
- This line executes the compiled executable,
$bin
if the compilation succeeded, and passes all of the remaining command line arguments,"$@"
to the compiled executable.
status=$?; \
- This line stores the status resulting from the attempt to compile and execute the program.
rm $bin; \
- This line deletes the compile binary after running the program.
exit $status
- This line exits the shell script interpreter, so that the rest of the C++ file will not be interpreted as shell script.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
you can use
chmod +x main.cpp
to make your program directly runnable on *nix, orsh main.cpp
in a terminal. I use this header to edit/compile/run the same C/C++ code on macOS and Windows (via gitbash)