make 失败无法停止 shell 脚本
Failure in make fails to halt shell script
我正在对 personal project using bash scripts (parts of the unit testing have been reviewed on Code Review)、cmake 和最新版本的 Fedora Linux 进行自动化构建和单元测试。积极测试在构建系统上通过,但是,当我在其中一个单元测试中强制 LD 失败时,构建仍然在更高级别通过。它需要在所有级别上都失败。
这是由 cmake 命令生成的 make 的错误消息:
/home/pacman/Documents/projects/VMWithEditor/VMWithEditor/human_readable_program_format.c:179: multiple definition of `HRF_delete_linked_list_of_program_steps'; CMakeFiles/Run_All_Unit_Tests.exe.dir/home/pacman/Documents/projects/VMWithEditor/VMWithEditor/UnitTests/HRF_UnitTest/HRF_UnitTest/unit_test_human_readable_program_format.c.o:/home/pacman/Documents/projects/VMWithEditor/VMWithEditor/UnitTests/RunAllUnitTests/RunAllUnitTests/../../../human_readable_program_format.c:179: first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Run_All_Unit_Tests.exe.dir/build.make:433: Run_All_Unit_Tests.exe] Error 1
make[2]: Leaving directory '/home/pacman/Documents/projects/VMWithEditor/VMWithEditor/UnitTests/RunAllUnitTests/RunAllUnitTests/Debug'
make[1]: *** [CMakeFiles/Makefile2:95: CMakeFiles/Run_All_Unit_Tests.exe.dir/all] Error 2
make[1]: Leaving directory '/home/pacman/Documents/projects/VMWithEditor/VMWithEditor/UnitTests/RunAllUnitTests/RunAllUnitTests/Debug'
make: *** [Makefile:103: all] Error 2
这是顶级shell脚本的输出,最后2个构建不应该执行:
Building CommandLine_UnitTest/CommandLine_UnitTest
Building ControlConsole_UnitTest/ControlConsole_UnitTest
Building Editor_UnitTest/Editor_UnitTest
Building HRF_UnitTest/HRF_UnitTest
Building Parser_Unit_Test/Parser_Unit_Test
Building RunAllUnitTests/RunAllUnitTests
Building State_Machine_Unit_Test/State_Machine_Unit_Test
Building VirtualMachine_UnitTest/VirtualMachine_UnitTest
这是 shell 脚本,它应该不会失败:
buildDebug.sh
#! /bin/sh
# Create a Debug build directory and then build the target within the Debug directory
# Stop on any build errors and stop the parent process.
mkdir Debug
cd Debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
retVal=$?
if [ $retVal -ne 0 ]; then
echo "\n\ncmake failed $retval!\n\n"
exit $retVal
fi
make VERBOSE=1
if [ $retVal -ne 0 ]; then
echo "\n\nmake failed! $retval\n\n"
exit $retVal
fi
前一个shell脚本被这个shell脚本调用,子目录中有8个前shell脚本的实例。
buildAllDebug.sh
#! /bin/sh
# Build the debug version of all the unit tests
# Stop on any build errors.
for i in *
do
if [ -d $i ] ; then
TESTDIRECTORY="$i/$i"
SHELLFILE="$TESTDIRECTORY/buildDebug.sh";
if [ -f $SHELLFILE ] ; then
echo "Building $TESTDIRECTORY";
cd "$TESTDIRECTORY"
./buildDebug.sh >& buildDebuglog.txt
retVal=$?
if [ $retVal -ne 0 ]; then
exit $retVal
fi
cd ../..
fi
fi
done;
这会生成报告错误的 make 文件:
CMakeLists.txt
cmake_minimum_required(VERSION 3.18.4)
set(EXECUTABLE_NAME "Run_All_Unit_Tests.exe")
project(${EXECUTABLE_NAME} LANGUAGES C VERSION 1.0)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(GCC_WARN_COMPILE_FLAGS " -Wall ")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_WARN_COMPILE_FLAGS}")
endif()
set(VM_SRC_DIR "../../..")
set(COMMON_TEST_DIR "../../Common_UnitTest_Code")
set(LEXICAL_TEST_DIR "../../State_Machine_Unit_Test/State_Machine_Unit_Test")
set(PARSER_TEST_DIR "../../Parser_Unit_Test/Parser_Unit_Test")
set(CMD_LINE_TEST_DIR "../../CommandLine_UnitTest/CommandLine_UnitTest")
set(HRF_TEST_DIR "../../HRF_UnitTest/HRF_UnitTest")
add_executable(${EXECUTABLE_NAME}
run_all_unit_tests_main.c
${HRF_TEST_DIR}/hrf_unit_test_main.c
${HRF_TEST_DIR}/unit_test_human_readable_program_format.c
${LEXICAL_TEST_DIR}/lexical_analyzer_unit_test_main.c
${LEXICAL_TEST_DIR}/internal_character_transition_unit_tests.c
${LEXICAL_TEST_DIR}/internal_sytax_state_tests.c
${LEXICAL_TEST_DIR}/lexical_analyzer_test_data.c
${LEXICAL_TEST_DIR}/lexical_analyzer_unit_test_utilities.c
${VM_SRC_DIR}/error_reporting.c
${VM_SRC_DIR}/safe_string_functions.c
${VM_SRC_DIR}/arg_flags.c
${VM_SRC_DIR}/file_io_vm.c
${VM_SRC_DIR}/opcode.c
${VM_SRC_DIR}/parser.c
${VM_SRC_DIR}/default_program.c
${VM_SRC_DIR}/human_readable_program_format.c
${VM_SRC_DIR}/lexical_analyzer.c
${VM_SRC_DIR}/virtual_machine.c
${PARSER_TEST_DIR}/parser_unit_test_main.c
${PARSER_TEST_DIR}/internal_parser_tests.c
${PARSER_TEST_DIR}/parser_unit_test.c
${CMD_LINE_TEST_DIR}/command_line_unit_test_main.c
${VM_SRC_DIR}/error_reporting.c
${VM_SRC_DIR}/arg_flags.c
${VM_SRC_DIR}/safe_string_functions.c
${COMMON_TEST_DIR}/unit_test_logging.c
)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED True)
configure_file(VMWithEditorConfig.h.in VMWithEditorConfig.h)
target_compile_definitions(${EXECUTABLE_NAME} PUBLIC UNIT_TESTING)
target_compile_definitions(${EXECUTABLE_NAME} PUBLIC ALL_UNIT_TESTING)
target_include_directories(${EXECUTABLE_NAME} PUBLIC "${PROJECT_BINARY_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${VM_SRC_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${COMMON_TEST_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${LEXICAL_TEST_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${CMD_LINE_TEST_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${PARSER_TEST_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${HRF_TEST_DIR}")
构建的目录结构:
这是由 ls -R 生成的,然后经过编辑删除了这个问题不需要的内容。
/UnitTests/:
buildAllDebug.sh
buildAll.log
buildDebug.sh
buildRelease.sh
CommandLine_UnitTest
Common_UnitTest_Code
ControlConsole_UnitTest
DirStructure.txt
Editor_UnitTest
HRF_UnitTest
Parser_Unit_Test
RunAllUnitTests
State_Machine_Unit_Test
UnitTests
VirtualMachine_UnitTest
/UnitTests/CommandLine_UnitTest:
/UnitTests/CommandLine_UnitTest/CommandLine_UnitTest:
buildDebuglog.txt
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/Common_UnitTest_Code:
/UnitTests/ControlConsole_UnitTest:
/UnitTests/ControlConsole_UnitTest/ControlConsole_UnitTest:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/Editor_UnitTest:
/UnitTests/Editor_UnitTest/Editor_UnitTest:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/HRF_UnitTest:
/UnitTests/HRF_UnitTest/HRF_UnitTest:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/Parser_Unit_Test:
/UnitTests/Parser_Unit_Test/Parser_Unit_Test:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/RunAllUnitTests:
/UnitTests/RunAllUnitTests/RunAllUnitTests:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/State_Machine_Unit_Test:
/UnitTests/State_Machine_Unit_Test/State_Machine_Unit_Test:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/UnitTests:
/UnitTests/VirtualMachine_UnitTest:
/UnitTests/VirtualMachine_UnitTest/VirtualMachine_UnitTest:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
你有:
make VERBOSE=1
if [ $retVal -ne 0 ]; then
但是retVal
仍然是cmake
命令的return代码。要么重置它,要么直接测试 $?
。
我正在对 personal project using bash scripts (parts of the unit testing have been reviewed on Code Review)、cmake 和最新版本的 Fedora Linux 进行自动化构建和单元测试。积极测试在构建系统上通过,但是,当我在其中一个单元测试中强制 LD 失败时,构建仍然在更高级别通过。它需要在所有级别上都失败。
这是由 cmake 命令生成的 make 的错误消息:
/home/pacman/Documents/projects/VMWithEditor/VMWithEditor/human_readable_program_format.c:179: multiple definition of `HRF_delete_linked_list_of_program_steps'; CMakeFiles/Run_All_Unit_Tests.exe.dir/home/pacman/Documents/projects/VMWithEditor/VMWithEditor/UnitTests/HRF_UnitTest/HRF_UnitTest/unit_test_human_readable_program_format.c.o:/home/pacman/Documents/projects/VMWithEditor/VMWithEditor/UnitTests/RunAllUnitTests/RunAllUnitTests/../../../human_readable_program_format.c:179: first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Run_All_Unit_Tests.exe.dir/build.make:433: Run_All_Unit_Tests.exe] Error 1
make[2]: Leaving directory '/home/pacman/Documents/projects/VMWithEditor/VMWithEditor/UnitTests/RunAllUnitTests/RunAllUnitTests/Debug'
make[1]: *** [CMakeFiles/Makefile2:95: CMakeFiles/Run_All_Unit_Tests.exe.dir/all] Error 2
make[1]: Leaving directory '/home/pacman/Documents/projects/VMWithEditor/VMWithEditor/UnitTests/RunAllUnitTests/RunAllUnitTests/Debug'
make: *** [Makefile:103: all] Error 2
这是顶级shell脚本的输出,最后2个构建不应该执行:
Building CommandLine_UnitTest/CommandLine_UnitTest
Building ControlConsole_UnitTest/ControlConsole_UnitTest
Building Editor_UnitTest/Editor_UnitTest
Building HRF_UnitTest/HRF_UnitTest
Building Parser_Unit_Test/Parser_Unit_Test
Building RunAllUnitTests/RunAllUnitTests
Building State_Machine_Unit_Test/State_Machine_Unit_Test
Building VirtualMachine_UnitTest/VirtualMachine_UnitTest
这是 shell 脚本,它应该不会失败:
buildDebug.sh
#! /bin/sh
# Create a Debug build directory and then build the target within the Debug directory
# Stop on any build errors and stop the parent process.
mkdir Debug
cd Debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
retVal=$?
if [ $retVal -ne 0 ]; then
echo "\n\ncmake failed $retval!\n\n"
exit $retVal
fi
make VERBOSE=1
if [ $retVal -ne 0 ]; then
echo "\n\nmake failed! $retval\n\n"
exit $retVal
fi
前一个shell脚本被这个shell脚本调用,子目录中有8个前shell脚本的实例。
buildAllDebug.sh
#! /bin/sh
# Build the debug version of all the unit tests
# Stop on any build errors.
for i in *
do
if [ -d $i ] ; then
TESTDIRECTORY="$i/$i"
SHELLFILE="$TESTDIRECTORY/buildDebug.sh";
if [ -f $SHELLFILE ] ; then
echo "Building $TESTDIRECTORY";
cd "$TESTDIRECTORY"
./buildDebug.sh >& buildDebuglog.txt
retVal=$?
if [ $retVal -ne 0 ]; then
exit $retVal
fi
cd ../..
fi
fi
done;
这会生成报告错误的 make 文件:
CMakeLists.txt
cmake_minimum_required(VERSION 3.18.4)
set(EXECUTABLE_NAME "Run_All_Unit_Tests.exe")
project(${EXECUTABLE_NAME} LANGUAGES C VERSION 1.0)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(GCC_WARN_COMPILE_FLAGS " -Wall ")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_WARN_COMPILE_FLAGS}")
endif()
set(VM_SRC_DIR "../../..")
set(COMMON_TEST_DIR "../../Common_UnitTest_Code")
set(LEXICAL_TEST_DIR "../../State_Machine_Unit_Test/State_Machine_Unit_Test")
set(PARSER_TEST_DIR "../../Parser_Unit_Test/Parser_Unit_Test")
set(CMD_LINE_TEST_DIR "../../CommandLine_UnitTest/CommandLine_UnitTest")
set(HRF_TEST_DIR "../../HRF_UnitTest/HRF_UnitTest")
add_executable(${EXECUTABLE_NAME}
run_all_unit_tests_main.c
${HRF_TEST_DIR}/hrf_unit_test_main.c
${HRF_TEST_DIR}/unit_test_human_readable_program_format.c
${LEXICAL_TEST_DIR}/lexical_analyzer_unit_test_main.c
${LEXICAL_TEST_DIR}/internal_character_transition_unit_tests.c
${LEXICAL_TEST_DIR}/internal_sytax_state_tests.c
${LEXICAL_TEST_DIR}/lexical_analyzer_test_data.c
${LEXICAL_TEST_DIR}/lexical_analyzer_unit_test_utilities.c
${VM_SRC_DIR}/error_reporting.c
${VM_SRC_DIR}/safe_string_functions.c
${VM_SRC_DIR}/arg_flags.c
${VM_SRC_DIR}/file_io_vm.c
${VM_SRC_DIR}/opcode.c
${VM_SRC_DIR}/parser.c
${VM_SRC_DIR}/default_program.c
${VM_SRC_DIR}/human_readable_program_format.c
${VM_SRC_DIR}/lexical_analyzer.c
${VM_SRC_DIR}/virtual_machine.c
${PARSER_TEST_DIR}/parser_unit_test_main.c
${PARSER_TEST_DIR}/internal_parser_tests.c
${PARSER_TEST_DIR}/parser_unit_test.c
${CMD_LINE_TEST_DIR}/command_line_unit_test_main.c
${VM_SRC_DIR}/error_reporting.c
${VM_SRC_DIR}/arg_flags.c
${VM_SRC_DIR}/safe_string_functions.c
${COMMON_TEST_DIR}/unit_test_logging.c
)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED True)
configure_file(VMWithEditorConfig.h.in VMWithEditorConfig.h)
target_compile_definitions(${EXECUTABLE_NAME} PUBLIC UNIT_TESTING)
target_compile_definitions(${EXECUTABLE_NAME} PUBLIC ALL_UNIT_TESTING)
target_include_directories(${EXECUTABLE_NAME} PUBLIC "${PROJECT_BINARY_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${VM_SRC_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${COMMON_TEST_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${LEXICAL_TEST_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${CMD_LINE_TEST_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${PARSER_TEST_DIR}")
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${HRF_TEST_DIR}")
构建的目录结构:
这是由 ls -R 生成的,然后经过编辑删除了这个问题不需要的内容。
/UnitTests/:
buildAllDebug.sh
buildAll.log
buildDebug.sh
buildRelease.sh
CommandLine_UnitTest
Common_UnitTest_Code
ControlConsole_UnitTest
DirStructure.txt
Editor_UnitTest
HRF_UnitTest
Parser_Unit_Test
RunAllUnitTests
State_Machine_Unit_Test
UnitTests
VirtualMachine_UnitTest
/UnitTests/CommandLine_UnitTest:
/UnitTests/CommandLine_UnitTest/CommandLine_UnitTest:
buildDebuglog.txt
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/Common_UnitTest_Code:
/UnitTests/ControlConsole_UnitTest:
/UnitTests/ControlConsole_UnitTest/ControlConsole_UnitTest:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/Editor_UnitTest:
/UnitTests/Editor_UnitTest/Editor_UnitTest:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/HRF_UnitTest:
/UnitTests/HRF_UnitTest/HRF_UnitTest:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/Parser_Unit_Test:
/UnitTests/Parser_Unit_Test/Parser_Unit_Test:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/RunAllUnitTests:
/UnitTests/RunAllUnitTests/RunAllUnitTests:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/State_Machine_Unit_Test:
/UnitTests/State_Machine_Unit_Test/State_Machine_Unit_Test:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
/UnitTests/UnitTests:
/UnitTests/VirtualMachine_UnitTest:
/UnitTests/VirtualMachine_UnitTest/VirtualMachine_UnitTest:
buildDebug.sh
buildRelease.sh
CMakeLists.txt
你有:
make VERBOSE=1
if [ $retVal -ne 0 ]; then
但是retVal
仍然是cmake
命令的return代码。要么重置它,要么直接测试 $?
。