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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 \
#!/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'; \
$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"; \
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 \
$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 "$@"; \
$bin
if the compilation succeeded, and passes all of the remaining command line arguments,"$@"
to the compiled executable.status=$?; \
rm $bin; \
exit $status