我終於厭倦了makefile,並編寫了自己的bash腳本來編譯。我寫了所有的東西,它的效果很好,但由於某種原因,當我嘗試用ctrl-c取消它時,它有時會凍結。這裏是腳本:Bash腳本在發送時凍結SIGINT
#!/bin/bash
# Just to see if the script even sees the SIGINT
trap caught SIGINT
caught() { echo "hi"; }
compile() {
cpp=$(echo "$1" | sed -e 's/$/.cpp/' -e 's/^/src\//')
o=$(echo "$1" | sed -e 's/$/.o/' -e "s/^/$build_dir\//")
echo "$compile -c $cpp -o $o"
eval "$compile -c $cpp -o $o"
return $?
}
# I know this isn't normal, but I hate it when I forget to include something
# in the header and it fails way down the line
compile_h() {
h=$(echo "$1" | sed -e 's/$/.h/' -e 's/^/src\//')
o=$(echo "$1" | sed -e 's/$/.o/' -e "s/^/$build_dir\/headers\//")
echo "$compile -c $h -o /dev/null"
eval "$compile -x c++ -c $h -o $o"
if [ $? -ne 0 ]; then
return 1
fi
rm "$o"
return 0
}
build_type=$(awk 'NR==1' .build_options)
compile_command_debug=$(awk 'NR==2' .build_options)
link_command_debug=$(awk 'NR==3' .build_options)
compile_command_production=$(awk 'NR==4' .build_options)
link_command_production=$(awk 'NR==5' .build_options)
libraries=$(awk 'NR==6' .build_options)
# Make options for this build
build_dir="build"
compile="$compile_command_debug"
link="$link_command_debug"
if [ "$build_type" == "production" ]; then
build_dir="buildp"
compile="$compile_command_production"
link="$link_command_production"
fi
# These options need to be changeable later
output="game"
job_number=5
# There are more options, but they aren't important for this problem
while [ "$1" != "" ]; do
if [ "$1" == "clean" ]; then
rm -r $build_dir/*
fi
shift
done
# Get filenames
cpps=$(find src -name *.cpp | sed -e 's/src\///' -e 's/.cpp//' | sort)
hs=$(find src -name *.h | sed -e 's/src\///' -e 's/.h//' | sort)
# Ensure that all directories exist
directories=$(find src -type d | tail --lines=+2 | sed 's/src\///' | sort)
if [ ! -d "$build_dir/headers" ]; then
mkdir "$build_dir/headers"
fi
for dir in $directories; do
if [ ! -d "$build_dir/$dir" ]; then
mkdir "$build_dir/$dir"
fi
if [ ! -d "$build_dir/headers/$dir" ]; then
mkdir "$build_dir/headers/$dir"
fi
done
all_o="" # To be used for linking
# Determine what files need to be compiled
cpp_needed=""
h_needed=""
link_needed=false
# Check cpp files
for cpp_base in $cpps; do
o=$(echo "$cpp_base" | sed -e 's/$/.o/' -e "s/^/$build_dir\//")
all_o="$all_o $o"
d_file=$(echo "$cpp_base" | sed -e 's/$/.d/' -e "s/^/$build_dir\//")
if [ -f "$d_file" ]; then
d=$(<"$d_file")
d=$(echo "$d" | tr " " "\n" | tail --lines=+2 | grep "s")
if [ "$link_needed" = false ]; then
if [ "$o" -nt "$output" ]; then
link_needed=true
fi
fi
for dep in $d; do
if [ "$dep" -nt "$o" ]; then
if [ "$cpp_needed" == "" ]; then cpp_needed="$cpp_base"
else cpp_needed="$cpp_needed $cpp_base"
fi
link_needed=true
break
fi
done
else
if [ "$cpp_needed" == "" ]; then cpp_needed="$cpp_base"
else cpp_needed="$cpp_needed $cpp_base"
fi
link_needed=true
fi
done
# Check h files
for h_base in $hs; do
d_file=$(echo "$h_base" | sed -e 's/$/.d/' -e "s/^/$build_dir\/headers\//")
if [ -f "$d_file" ]; then
d=$(<"$d_file")
d=$(echo "$d" | tr " " "\n" | tail --lines=+2 | grep "s")
for dep in $d; do
if [ "$dep" -nt "$d_file" ]; then
if [ "$h_needed" == "" ]; then h_needed="$h_base"
else h_needed="$h_needed $h_base"
fi
break
fi
done
else
if [ "$h_needed" == "" ]; then h_needed="$h_base"
else h_needed="$h_needed $h_base"
fi
fi
done
# Compile
did_something=false
# Compile hs
while [ "$h_needed" != "" ]; do
for index in $(seq 1 $job_number); do
if [ "$h_needed" == "" ]; then break; fi
if ! kill -0 ${pids[index]} 2>/dev/null; then
new_file=$(echo "$h_needed" | awk '{print $1;}')
if [ $(echo "$h_needed" | wc -w) -eq 1 ]; then h_needed=""
else h_needed=$(echo "$h_needed" | cut -d " " -f2-)
fi
compile_h "$new_file" &
pids[index]=$!
did_something=true
fi
done
wait -n
if [ $? -ne 0 ]; then
wait
exit 1
fi
done
while [ $(pgrep -c -P$$) -gt 0 ]; do
wait -n
if [ $? -ne 0 ]; then
wait
exit 1
fi
done
# Compile cpps
while [ "$cpp_needed" != "" ]; do
for index in $(seq 1 $job_number); do
if [ "$cpp_needed" == "" ]; then break; fi
if ! kill -0 ${pids[index]} 2>/dev/null; then
new_file=$(echo "$cpp_needed" | awk '{print $1;}')
if [ $(echo "$cpp_needed" | wc -w) -eq 1 ]; then cpp_needed=""
else cpp_needed=$(echo "$cpp_needed" | cut -d " " -f2-)
fi
compile "$new_file" &
pids[index]=$!
did_something=true
fi
done
wait -n
if [ $? -ne 0 ]; then
wait
exit 1
fi
done
while [ $(pgrep -c -P$$) -gt 0 ]; do
wait -n
if [ $? -ne 0 ]; then
wait
exit 1
fi
done
# Compile program
if [ "$link_needed" = true ]; then
echo "$link $all_o -o game $libraries"
eval "$link $all_o -o game $libraries"
did_something=true
fi
# Make a message if nothing compiled
if [ "$did_something" = false ]; then
echo "Program is already compiled."
fi
它通常是完美的。但是,有時候,當我嘗試用ctrl-c取消它時,它會凍結。通過一些調試,我發現當腳本沒有創建新的工作時,ctrl-c就可以正常工作。但是當它處於創建新工作的中間時,它會凍結劇本。它甚至不會捕獲SIGINT(這是「回聲嗨」的東西是在頂部)。我真的不知道發生了什麼事。有人知道發生了什麼事嗎?謝謝!
編輯:我意識到我應該提到我使用g ++來編譯。
再次編輯:這是一個更簡化的腳本版本。你仍然需要設置一些文件進行編譯,如果你想測試一下:
#!/bin/bash
# Just to see if the script even sees the SIGINT
trap caught SIGINT
caught() { echo "hi"; }
# I know this isn't normal, but I hate it when I forget to include something
# in the header and it fails way down the line
compile_h() {
h=$(echo "$1" | sed -e 's/$/.h/' -e 's/^/src\//')
o=$(echo "$1" | sed -e 's/$/.o/' -e "s/^/$build_dir\/headers\//")
echo "$compile -c $h -o /dev/null"
eval "$compile -x c++ -c $h -o $o"
if [ $? -ne 0 ]; then
return 1
fi
rm "$o"
return 0
}
build_type="debug"
build_dir="build"
compile="g++"
job_number=5
# Get filenames
hs=$(find src -name *.h | sed -e 's/src\///' -e 's/.h//' | sort)
h_needed=$(echo $hs)
# Compile hs
while [ "$h_needed" != "" ]; do
for index in $(seq 1 $job_number); do
if [ "$h_needed" == "" ]; then break; fi
if ! kill -0 ${pids[index]} 2>/dev/null; then
new_file=$(echo "$h_needed" | awk '{print $1;}')
if [ $(echo "$h_needed" | wc -w) -eq 1 ]; then h_needed=""
else h_needed=$(echo "$h_needed" | cut -d " " -f2-)
fi
compile_h "$new_file" &
pids[index]=$!
did_something=true
fi
done
wait -n
if [ $? -ne 0 ]; then
wait
exit 1
fi
done
while [ $(pgrep -c -P$$) -gt 0 ]; do
wait -n
if [ $? -ne 0 ]; then
wait
exit 1
fi
done
試着理解[mcve]。在這種情況下,尤其是「minimal」這個詞:) – jm666
......另外,最好使用configure + makefile作爲你自己發明的解決方案......(僅僅是imho)。 – jm666
我已經擺脫了我的實際版本的很多東西。問題是我不確定問題出在哪裏。 – sudgy