技術討論區 > 程式討論版
如何將 c++ 原始碼變成 shell script 執行 ^__^
(1/1)
Yamaka:
好久以前試過一次,不過沒試出來,今天再拿出來玩,終於弄出來了XD
目標是這樣:編寫好 c/c++ 程式碼之後,不手動跑 make 或是 gcc/g++ 編譯,
而是直接改原始碼的權限為可執行,然後就.....直接執行這個檔,例如:
--- 代碼: ---$ cat ex045.cc
#include <iostream>
int main(int argc, char **argv) {
std::cout << "Hello, World!!\n"
<< argc << "\n" << argv[1] << " " << argv[2]
<< std::endl;
return 0;
}
--- 程式碼結尾 ---
--- 引用 ---$ chmod +x ex045.cc
$ time ./ex045.cc 123 abc
Hello, World!!
3
123 abc
real 0m0.365s
user 0m0.304s
sys 0m0.048s
--- 引用結尾 ---
沒錯,就是要能夠直接跑 ./ex045.cc,不是編譯後的 ./ex045
中間測試過程就略過不提了,直接貼結果出來
--- 代碼: ---$ cat ex045.cc
//bin/true;CCE=$0;CCE="${CCE##*/}";CCE="/tmp/cc/${CCE%%.*}";[ ! -d "/tmp/cc" ]&&mkdir /tmp/cc/;if [ ! -f ${CCE} ] || [ `date -r $0 +%s` -gt `date -r ${CCE} +%s` ]; then /usr/bin/env clang++ -O3 -std=c++14 -o ${CCE} $0;fi; ${CCE} $@;exit
#include <iostream>
int main(int argc, char **argv) {
std::cout << "Hello, World!!\n"
<< argc << "\n" << argv[1] << " " << argv[2]
<< std::endl;
return 0;
}
--- 程式碼結尾 ---
跟其他 shell script 一樣,第一行對 c++ 來說是是註解
但卻是一串 bash 指令,這些指令會判斷原始碼與執行檔的檔案時間
必要的話就啟動編譯器編譯進行編譯,執行檔則丟到 /tmp/cc
最後再執行 /tmp/cc 資料夾裡的執行檔
這行最後面的『 exit 』指令是必要的
少了這行,bash 會一直往下讀取指令並執行...
第一次執行會先進行編譯,如果程式碼未修改過
之後再執行就不會編譯(直到 reboot)
--- 引用 ---$ time ./ex045.cc 123 abc
Hello, World!!
3
123 abc
real 0m0.365s
user 0m0.304s
sys 0m0.048s
$ time ./ex045.cc 123 abc
Hello, World!!
3
123 abc
real 0m0.022s
user 0m0.008s
sys 0m0.008s
--- 引用結尾 ---
Yamaka:
鞗改了一下,我把那一大串指令改寫成 .sh 檔放在 /usr/local/bin
--- 代碼: ---$ cat /usr/local/bin/cce.sh
#!/bin/bash
CCE=$1
CCE="${CCE##*/}"
CCE="/tmp/cc/${CCE%%.*}"
[ ! -d "/tmp/cc" ] && mkdir /tmp/cc/
if [ ! -f ${CCE} ] || [ `date -r $1 +%s` -gt `date -r ${CCE} +%s` ]; then
/usr/bin/env clang++ -O3 -std=c++14 -o ${CCE} $1
fi
shift
#echo ${CCE}
${CCE} $@
--- 程式碼結尾 ---
$ sudo chmod +x /usr/local/bin/cce.sh
c++ 第一行就可以簡潔一點
--- 代碼: ---$ cat ex045.cc
//usr/local/bin/cce.sh $0 $@;exit
#include <iostream>
int main(int argc, char **argv) {
std::cout << "Hello, World!!\n"
<< argc << "\n" << argv[1] << " " << argv[2]
<< std::endl;
return 0;
}
--- 程式碼結尾 ---
執行效果一樣 ^^
$ time ./ex045.cc 123 abc
Hello, World!!
3
123 abc
real 0m0.026s
user 0m0.008s
sys 0m0.012s
dark:
這是什麼觀念與技術 ?
照貼試了一下
/usr/bin/env: clang++: 沒有此一檔案或目錄
Yamaka:
簡單來說,就是用 shell script 寫的簡易版的 make
檢查 c++ 程式檔對應的執行檔是否存在
並且比對程式檔與執行檔的時間
如果程式檔比較新就重新編譯
然後執行編譯後的執行檔
clang++ 是我用的 c++ 編譯器
dark:
原來如此 ... 了解了
將
clang++ -O3 -std=c++14 -o ${CCE} $1
改為自己習慣編譯的方式即可
導覽
[0] 文章列表
前往完整版本