I often put compilation notes in the comments at the top of small .cpp programs. These are just reminders to me of the flags I need to set in g++ to compile the program. For bigger programs I use Xcode or Makefiles, but often if I'm just testing a small idea I don't want that overhead. I had a funny idea today that my .cpp file could act as both a bash script and as C++ code. Then I could execute the .cpp file (as a bash script) which would set up the compiler and then compile itself. Here's a proof of concept, save this in main.cpp
#!/bin/bash
//usr/bin/tail -n +2 $0 | g++ -o main -x c++ - && exit
#include <cstdio>
int main(int argc,char * argv[])
{
printf("Hello, world\n");
return 0;
}
Make it executable with chmod +x main.cpp
To compile just execute the cpp file:
./main.cpp
This creates the real binary of the program which you can execute with:
./main
Update: If you don't like the hassle of making the binary you can just run the binary right after you compile it, then delete it immediately. Do this by changing the second line to:
#!/bin/bash
//usr/bin/tail -n +2 $0 | g++ -o main -x c++ - && ./main && rm main && exit
#include <cstdio>
int main(int argc,char * argv[])
{
printf("Hello, world\n");
return 0;
}
Update: With an additional hack you can have a full fledged bash script at the top of your .cpp file:
#!/bin/bash
/*/../bin/ls > /dev/null
# BEGIN BASH SCRIPT
printf "//" | cat - $0 | g++ -o .main -x c++ - && ./.main $@
rm -f .main
# END BASH SCRIPT
exit
*/
#include <cstdio>
int main(int argc,char * argv[])
{
printf("Hello, world\n");
return 0;
}
Update: Here's another one I found especially useful. This allows me to pipe the output to colormake to get colorized terminal compiler output.
#!/bin/bash
/*/../bin/ls > /dev/null
# BEGIN BASH SCRIPT
export PS4=""
set -o xtrace
printf "//" | cat - $0 | g++ -o .main -x c++ - && ./.main $@
rm -f .main
# END BASH SCRIPT
exit
*/
#include <cstdio>
int main(int argc,char * argv[])
{
printf("Hello, world\n");
return 0;
}
Then I pipe the output to colormake using:
./main.cpp 2>&1 | colormake.pl
Update: Yet another one. This time works with the debugger.
TEMP="$0.cpp" printf "//" | cat - $0 >$TEMP
#!/bin/bash
/*/../bin/ls > /dev/null
# BEGIN BASH SCRIPT
source ~/.profile
export PS4=""
set -o xtrace
printf "//" | cat - $0 |
g++ -g -O0 -std=c++11 -o .main $TEMP && \
/Applications/Xcode.app/Contents/Developer/usr/bin/lldb -b -o r ./main -- "$@"
rm -f .main
# END BASH SCRIPT
exit
*/
#include <cstdio>
int main(int argc,char * argv[])
{
printf("Hello, world\n");
return 0;
}
Update: I edited the above to include source ~/.profile
. Seems with El Capitan Mac OS 10.11 the DYLD_FALLBACK_LIBRARY_PATH
setting is not persistent when call a script from vim
.