|
2 | 2 |
|
3 | 3 | ## Concept |
4 | 4 |
|
| 5 | +### In short (for experienced linux users) |
| 6 | + |
| 7 | +- Create C++ source file, prepend it with shebang line `#!/path/to/build-n-run`, make it executable `chmod +x script.cpp` and run: `./script.cpp`. |
| 8 | + |
| 9 | +- `build-n-run` compiles `script.cpp` to `~/bin/build-n-run.compiled/` **only if source file is newer than compiled binary**, and then runs compiled binary. |
| 10 | + |
| 11 | +### In detail |
| 12 | + |
5 | 13 | They say compiled languages are inconvenient for scripting because you have to recompile your script everytime you edit it. A little program `build-n-run.cpp` presented in this repo solves the problem. |
6 | 14 |
|
7 | 15 | In bash scripts, first line always starts with "[shebang](https://en.wikipedia.org/wiki/Shebang_(Unix))" followed by name of a bash interpreter. When you run bash script, effectively bash interpreter is run and this script is passed to it as first argument. |
8 | 16 |
|
9 | 17 | #!/bin/bash |
10 | 18 | echo "Hello world!" |
11 | 19 |
|
12 | | -Same approach is used for Python scripts, Scala scripts, etc. So I did the same: file `hello.cpp` in this repo is normal C++ program prepended with shebang line: |
| 20 | +Same approach is used for Python scripts, Scala scripts, etc. So I did the same: example script `hello.cpp` in this repo is normal C++ program prepended with shebang line: |
13 | 21 |
|
14 | 22 | #!/usr/local/bin/build-n-run |
15 | 23 | #include <stdio.h> |
16 | 24 | int main() { |
17 | 25 | puts("Hello world!"); |
18 | 26 | } |
19 | 27 |
|
20 | | -`build-n-run` automatically recompiles script *if it was edited* (by comparing source and binary modification times) and then runs it: |
| 28 | +`build-n-run` automatically recompiles script **if it is new or edited** (i.e. if compiled binary does not exist or if source file's modification time is newer than binary's) and then runs it: |
21 | 29 |
|
22 | 30 | $ hello.cpp |
23 | | - Recompiling... <--- first time you run your script, it's recompiled |
| 31 | + Recompiling... <--- First time you run your script, it's recompiled. |
24 | 32 | Hello world! |
25 | 33 |
|
26 | 34 | $ hello.cpp |
27 | | - Hello world! |
| 35 | + Hello world! <--- No recompilation on next run if script is unchanged. |
28 | 36 |
|
29 | 37 | ## Installation and use |
30 | 38 |
|
31 | 39 | 1. Download `build-n-run.cpp` from this repo. |
32 | 40 |
|
33 | | -2. [Optional] Check its source code: update GCC options used to compile your scripts; remove "Recompiling..." message if it messes with our scripts' output. |
| 41 | +2. (Optional) Check its source code: you might want to update GCC options used to compile your scripts, or remove "Recompiling..." message if it messes with our scripts' output. |
34 | 42 |
|
35 | | -3. Compile and install it. I install to `/usr/local/bin`, so I run this command as root. You can install it anywhere you want, just don't forget to edit path in `hello.cpp`'s shebang line. I use gcc 7.3.0, so I explicitly link `libstdc++fs.a` which implements `std::experimental::filesystem`. |
| 43 | +3. Compile and install it. I install to `/usr/local/bin`, so I run this command as root; you can install it anywhere you want, just don't forget to update path in scripts' shebang line. I use gcc 7.3.0, so I explicitly link `libstdc++fs.a` which implements `std::experimental::filesystem`. |
36 | 44 |
|
37 | 45 | # g++ build-n-run.cpp -lstdc++fs -o /usr/local/bin/build-n-run |
38 | 46 |
|
39 | | -4. Create directory for compiled scripts. Its full path must be the same as installed program's plus `.compiled` suffix. If that directory is shared among multiple users, grant global access to it. |
40 | | - |
41 | | - # mkdir /usr/local/bin/build-n-run.compiled |
42 | | - # chmod a+rwx /usr/local/bin/build-n-run.compiled |
43 | | - |
44 | | -That's all. Now write C++ program with shebang at first line, *chmod it to be executable*, and run: |
| 47 | +That's all. Now write C++ program with shebang line, **chmod it to be executable**, and run: |
45 | 48 |
|
46 | 49 | $ chmod +x hello.cpp |
47 | 50 | $ ./hello.cpp |
48 | 51 | Recompiling... |
49 | 52 | Hello world! |
50 | 53 |
|
51 | | -Now let's take a look at `build-n-run.compiled` directory: |
| 54 | +Let's take a look at `~/bin/build-n-run.compiled` directory: |
52 | 55 |
|
53 | | - $ ls /usr/local/bin/build-n-run.compiled |
| 56 | + $ ls ~/bin/build-n-run.compiled |
54 | 57 | home--me--tmp--hello |
55 | 58 |
|
56 | 59 | I downloaded `hello.cpp` to `/home/me/tmp`, and compiled binary's name reflects source's full path, slashes replaced with `"--"`. |
| 60 | + |
| 61 | +## Security concerns |
| 62 | + |
| 63 | +Compiled cache is inside user's home, so scripts compiled by one user cannot be run by other users (see issue #1). |
0 commit comments