2014-06-27 67 views
4

請參閱Call functions in other files in C++ and OpenCV初始問題。我正在使用的代碼詳細給出。這是一個子問題。BASH腳本來編譯多個C++文件 - OpenCV

我有一個bash腳本:

echo "compiling $1" 
if [[ $1 == *.c ]] 
then 
    gcc -ggdb `pkg-config --cflags opencv` -o `basename $1 .c` $1 `pkg-config --libs opencv`; 
elif [[ $1 == *.cpp ]] 
then 
    g++ -ggdb `pkg-config --cflags opencv` -o `basename $1 .cpp` $1 `pkg-config --libs opencv`; 
else 
    echo "Please compile only .c or .cpp files" 
fi 
echo "Output file => ${1%.*}" 

上面BASH腳本用於使用./script.sh input.cpp編譯OpenCV的代碼。
我懷疑是我怎麼能修改在同一時間編譯多個文件,像我用我的主代碼像一些功能的另一個文件:
./script.sh input.cpp functions.cpp


編輯
作爲由約翰·B建議,我修改了我的bash腳本來

for f in "[email protected]"; do 
    echo "compiling $f" 
    if [[ $f == *.c ]] 
    then 
     gcc -ggdb `pkg-config --cflags opencv` -o `basename "$f" .c` "$f" `pkg-config --libs opencv` 
    elif [[ $f == *.cpp ]] 
    then 
     g++ -ggdb `pkg-config --cflags opencv` -o `basename "$f" .cpp` "$f" `pkg-config --libs opencv` 
    else 
     echo "$f is not .c or .cpp file" 
    fi 
    echo "Output file => ${f%.*}" 
done 

但現在,我得到以下錯誤:

compiling draw_shapes.cpp 
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: In function `_start': 
(.text+0x20): undefined reference to `main' 
collect2: error: ld returned 1 exit status 
Output file => draw_shapes 
compiling test.cpp 
/tmp/ccW65wuP.o: In function `main': 
/home/kanishka/Desktop/opencv test/test.cpp:31: undefined reference to `draw_line(cv::Mat, cv::Point_<int>, cv::Point_<int>, int, int, int)' 
collect2: error: ld returned 1 exit status 
Output file => test 
+0

相關:http://stackoverflow.com/questions/24442836/call -functions功能於其他 - 文件 - 在-C-和OpenCV的 –

+0

+1的鏈接。謝謝@Ben! –

+3

正常最好的做法是使用一個'makefile',或更現代的等同物中的一個。 「make」是爲了避免這種shell腳本在很多情況下被髮明出來的。 –

回答

0

的直接和簡單的解決方案:

創建包含以下內容的另一個腳本文件:

./script.sh input.cpp 
./script.sh functions.cpp 

然後,不帶參數運行它:

./doit.sh 

你的新的腳本, doit.sh必須位於與現有script.sh相同的文件夾中。

請考慮投入時間學習體面的構建系統,如cmake。對於一個小型項目來說這可能是一種矯枉過正,但是當你的項目規模增長時,它變得值得投資。

+0

這沒有奏效。我仍然得到錯誤 未定義的引用'draw_line(cv :: Mat,cv :: Point_ ,cv :: Point_ ,int,int,int)'' –

+0

@KanishkaGanguly,你是否驗證過你正在合適由'pkg-config --libs opencv'返回的libs。另外請確保您在包含源代碼的相同目錄中調用腳本。不要''./script.sh/some/path/to/input.cpp' –

+0

@ DavidC.Rankin是的。代碼完美地運行一個單一的輸入文件。嘗試從鏈接的C++文件調用函數時發生該錯誤。 –

1

As Jonathan Leffler建議,最好使用makefile。但是如果你想使用Bash腳本,你可以調用[email protected]的所有參數並遍歷每個參數。

for f in "[email protected]"; do 
    echo "compiling $f" 
    if [[ $f == *.c ]] 
    then 
     gcc -ggdb `pkg-config --cflags opencv` -o `basename "$f" .c` "$f" `pkg-config --libs opencv` 
    elif [[ $f == *.cpp ]] 
    then 
     g++ -ggdb `pkg-config --cflags opencv` -o `basename "$f" .cpp` "$f" `pkg-config --libs opencv` 
    else 
     echo "$f is not .c or .cpp file" 
    fi 
    echo "Output file => ${f%.*}" 
done 
+0

千萬不要'$ @';總是['「$ @」'](http://stackoverflow.com/questions/255898/how-to-iterate-over-arguments-in-bash-script/256225#256225)! –

+0

@KanishkaGanguly:請!!!用額外信息更新問題!你不能在評論中格式化。 –

+0

@KanishkaGanguly我的答案只能解決您的問題中的信息,詢問如何在多個文件參數上執行您的腳本。 –

0

不是調試,而是寫起來比較容易。這給一展身手:

#!/bin/bash 

test -n "$1" || { echo "error: insufficient input, usage :${0##*/} filename.c (cpp)"; exit 1; } 

for source in "[email protected]"; do 

    ext="${source##*\.}" # file extension 
    fname="${source##*/}" 
    fname="${fname%\.*}" # base filename (no extension) 

    if test "$ext" == "c" ; then 

     gcc -ggdb `pkg-config --cflags opencv` \ 
     -o "$fname" "$source" \ 
     `pkg-config --libs opencv` 

    elif test "$ext" == "cpp" ; then 

     g++ -ggdb `pkg-config --cflags opencv` \ 
     -o "$fname" "$source" \ 
     `pkg-config --libs opencv` 

    else 
     echo "Please compile only .c or .cpp files" 

    fi 

done 

exit 0 
+0

請解釋此代碼。 另外,這與John B的建議有什麼不同? –

+0

它基本上是相同的代碼,但我不喜歡使用外部工具將filename.ext與基本名稱分開。我只是使用bash模式匹配/子字符串匹配/等等...我使用相同的循環爲每個輸入文件運行一次代碼:'for source in「$ @」; do'。之後,我只是將文件名/ ext從原始的'source'文件名中分離出來。然後它基本上是你的'c'或'cpp'文件的腳本。 –

+0

啊,明白了!謝謝! –

1

要在編輯說明問題:

要獲得編譯時,他們沒有「主」的功能,你將需要使用-c開關文件,所以編譯器生成的對象而不是可執行文件。進程列表的程序應該是這樣的:

g++ $src_file1 $src_file2 -Iincludes_directory -c -o obj/object1.o 
g++ $src_file3 $src_file4 -Iincludes_directory -c -o obj/object2.o 
g++ $src_file5 $src_file6 -Iincludes_directory -c -o obj/object3.o 
.... 
g++ $srcfileX $src_file_containing_main_function -Iincludes_directory -c -o obj/object_with_main.o 

當你有對象完成,是時候將它們連接在一起

g++ obj/* -o my_awesome_executable