作者 主題: 如何將 c++ 原始碼變成 shell script 執行 ^__^  (閱讀 1634 次)

0 會員 與 1 訪客 正在閱讀本文。

Yamaka

  • 俺是博士!
  • *****
  • 文章數: 4904
    • 檢視個人資料
    • http://www.ecmagic.com
好久以前試過一次,不過沒試出來,今天再拿出來玩,終於弄出來了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

  • 俺是博士!
  • *****
  • 文章數: 4904
    • 檢視個人資料
    • http://www.ecmagic.com
Re: 如何將 c++ 原始碼變成 shell script 執行 ^__^
« 回覆 #1 於: 2015-09-08 14:37 »
鞗改了一下,我把那一大串指令改寫成 .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

  • 俺是博士!
  • *****
  • 文章數: 1481
    • 檢視個人資料
Re: 如何將 c++ 原始碼變成 shell script 執行 ^__^
« 回覆 #2 於: 2016-10-11 01:28 »
這是什麼觀念與技術 ?

照貼試了一下

/usr/bin/env: clang++: 沒有此一檔案或目錄


Yamaka

  • 俺是博士!
  • *****
  • 文章數: 4904
    • 檢視個人資料
    • http://www.ecmagic.com
Re: 如何將 c++ 原始碼變成 shell script 執行 ^__^
« 回覆 #3 於: 2016-10-11 13:14 »
簡單來說,就是用 shell script 寫的簡易版的 make

檢查 c++ 程式檔對應的執行檔是否存在
並且比對程式檔與執行檔的時間
如果程式檔比較新就重新編譯
然後執行編譯後的執行檔

clang++ 是我用的 c++ 編譯器

dark

  • 俺是博士!
  • *****
  • 文章數: 1481
    • 檢視個人資料
Re: 如何將 c++ 原始碼變成 shell script 執行 ^__^
« 回覆 #4 於: 2016-10-11 16:13 »
原來如此 ... 了解了


clang++ -O3 -std=c++14 -o ${CCE} $1
改為自己習慣編譯的方式即可