막상 윈도우용으로 생성한 첫 번째 배치 파일을 리눅스에 적용하려고 하니 문제가 많았다.
하긴 make 한다던지 lcov 사용하는 것들이 찾아보니 원래 리눅스 용으로 개발된 것이라고 하니 더욱더 그럴 수 도 있겠다.
두 운영체제에서 동작할 수 있는 좀 더 통일된 방법이 필요했다.
구글링을 해보니 CMakeLists.txt를 가장 상위에 두고 add_subdirectory("하위 CMakeLists.txt 있는 경로")를 추가하여 가장 상위에서 executable 하나만 생성할 수 있는 것 같다.
그렇게 하자. 그게 각 폴더를 돌아다니면서 파싱하면서 난리치는 것보다 더 깔끔하고 근본적인 방법인 것 같다. 하는 김에 지난 번에 만든 파이썬 스크립트도 넣자.
아래와 execute.bat를 작성해서 가장 상위에서 하나의 executable을 만들고 이를 실행시켜 리포트를 작성하도록 변경했다.
@echo off
set PATH=%CD%\MingW64\mingw32\bin;%PATH%
pushd %CD%\Mocks
mingw32-make.exe
popd
cmake -G "MinGW Makefiles" CMakeLists.txt
mingw32-make.exe
call gCoverage.bat
if exist gTestResult (
rmdir /s /q gTestResult
)
md "%CD%\gTestResult"
set REPORT_DIR=%CD%\gTestResult
move %CD%\coverage_html %REPORT_DIR%\coverage_html
move %CD%\gcov %REPORT_DIR%\gcov
move %CD%\result.txt %REPORT_DIR%
set REPORT_DIR=%REPORT_DIR:\=/%
pushd %CD%\lcov-master
python test_report.py "%REPORT_DIR%/test_report.html" "%REPORT_DIR%/result.txt"
popd
REM Remove each test executable and each test report
for /r /d %%a in (*) do if exist "%%a\CMakeLists.txt" (
pushd %%a
REM rmdir /s /q CMakeFiles
del /q cmake_install.cmake
del /q CTestTestfile.cmake
del /q *.exe
del /q Makefile
popd
)
pushd %CD%\Mocks
REM mingw32-make.exe clean
popd
pushd %CD%\gTestResult
REM rmdir /s /q gcov
del /q result.txt
popd
rmdir /s /q CMakeFiles
rmdir /s /q Testing
del /q cmake_install.cmake
del /q CMakeCache.txt
del /q CTestTestfile.cmake
del /q Makefile
이를 위해서 가장 상위의 executable 출력 파일들을 가지고 리포트를 생성하도록 gCoverage.bat를 수정했다.
@echo off
set TARGET=FotaStatusNotify
set PATH=%VUC_DIR%\VUC_APP\UnitTest_GTest\MingW64\mingw32\bin;%PATH%
set OUTPUT_DIR=%CD%
set CUR_DIR=%CD%
set VUC_DIR=%CUR_DIR%\..\..
for %%i in ("%VUC_DIR%") do SET "VUC_DIR=%%~fi"
set SRC_DIR=%VUC_DIR%\VUC_APP\application\Source\
echo %SRC_DIR%
set LCOV_PREFIX_DIR=%VUC_DIR%\VUC_APP\application\Source
set LCOV_DIR=%VUC_DIR%\VUC_APP\UnitTest_GTest\lcov-master
set build_unittest_xxx=%CUR_DIR%\
REM CMakeFiles\%TARGET%.dir
echo %CUR_DIR%
echo %VUC_DIR%
echo %SRC_DIR%
echo %LCOV_PREFIX_DIR%
echo %LCOV_DIR%
echo %build_unittest_xxx%
for %%i in ("%LCOV_PREFIX_DIR%") do SET "absLCOV_PREFIX_DIR=%%~fi"
for %%i in ("%SRC_DIR%") do SET "absSRC_DIR=%%~fi"
REM pushd %absLCOV_PREFIX_DIR%
echo %absLCOV_PREFIX_DIR%
REM pushd %absSRC_DIR%
echo %absSRC_DIR%
REM call del *.xml
REM call del *.html
REM call del *.gcda
REM call del *.gcno
REM call "cd $(SRC_DIR) & del *.gcda"
for /r %%f in (*.gcda) do (
echo "Deleting %%f ..."
del %%f
)
REM popd
pushd %CUR_DIR%\CMakeFiles
for /r %%f in (*.gcda) do (
echo "Deleting %%f ..."
del %%f
)
popd
REM call "cd $(SRC_DIR) & del *.gcda"
REM for /r %%f in (%SRC_DIR%\*.gcda) do del %%f
REM for /r %%f in (%CUR_DIR%\CMakeFiles\*.gcda) do del %%f
IF EXIST gcov (
call rmdir gcov /s /q
)
IF EXIST coverage_html (
call rmdir coverage_html /s /q
)
REM GOTO :exit
call ctest -V -O result.txt
REM call %TARGET%.exe --gtest_output=xml:%TARGET%_result.xml
REM --gtest_filter=*PM_EEPROM_*
REM --gtest_filter=*updateTimeSyncFrame_MD_OK*
REM --gtest_filter=*Appl_RxCOMCbk_ComIPdu_ACU_DirverInfo_149R*
REM for /r %%f in (%build_unittest_xxx%\*.gcno) do copy %%f %OUTPUT_DIR%\%%~nxf
echo PATH DEFINE HERE**************************
set build_unittest_xxx=%build_unittest_xxx:\=/%
echo build_unittest_xxx=%build_unittest_xxx%
set absLCOV_PREFIX_DIR=%absLCOV_PREFIX_DIR:\=/%
echo absLCOV_PREFIX_DIR=%absLCOV_PREFIX_DIR%
set CUR_DIR=%CUR_DIR:\=/%
echo CUR_DIR=%CUR_DIR%
echo %LCOV_DIR%\lcov.bat %build_unittest_xxx% %absLCOV_PREFIX_DIR%
call %LCOV_DIR%\lcov.bat %build_unittest_xxx% %absLCOV_PREFIX_DIR%
:exit
리눅스 용은 더 간편했다.
execute.sh의 경우 다음과 같이 하면 되니 얼마나 편한가...
cd $BUILD_FOLDER
cmake ..
make
cd ..
./gCoverage.sh
rm -rf build
cd ./gTestResult
rm *.gcda *.gcno *.final *.info *.txt
cd ..
gCoverage.sh의 경우도 바꿀 것이 크게 없었다. lcov가 소스 코드 경로를 자꾸 이상하게 설정해서 genhtml 뒤에 -p 프리픽스 추가한 정도? 이래서 개발자들이 리눅스를 쓰나보다. 나는 리눅스 처음 써봤는데 완전 편함.
# project name, used to output message only
#BASEDIR=$(dirname $0)
BASEDIR="$( cd "$( dirname "$0" )" && pwd )"
project="GTEST_MAIN"
# build succesd unit test program
testProgram="./build/Makefile"
# google test result folder
gTestResultFolder="./gTestResult"
# the file used by google test coverage
gTestXML="./gTestResult/${project}.xml"
build_unittest_xxx="${BASEDIR}/build/"
#"/home/uidp3659/gmock.py/mock11/CMakeFiles/${project}.dir"
#"../mock11/CMakeFiles/Painter.dir/"
SOCDIR=${PWD%/*/*/*}
LCOV_PREFIX_DIR="${SOCDIR}/toyota-gdcm/package/conti-dcm/code/"
#../build_unittest_voc/
if [ "$1" == "clean" ]
then
if [ -d "${gTestResultFolder}" ];then
rm -rf ${gTestResultFolder}
fi
if [ -f "${gTestXML}" ];then
rm -f ${gTestXML}
fi
exit 0
fi
# rm gTestResultFolder
if [ -d ${gTestResultFolder} ];then
rm -rf ${gTestResultFolder}
fi
mkdir ${gTestResultFolder}
export GCOV_PREFIX=${gTestResultFolder}
export GCOV_PREFIX_STRIP=100
if [ -f "${gTestXML}" ];then
rm -f ${gTestXML}
fi
if [ ! -f "${testProgram}" ];then
echo "Run unit test converage failed. Please run make cmd to gererate '${testProgram}'. "
exit 1
fi
# run test program
cd ./build && ctest -V -O result.txt
cd ..
mv ./build/result.txt ./gTestResult
cd ./googletest
python test_report.py "${BASEDIR}/gTestResult/test_report.html" "${BASEDIR}/gTestResult/result.txt"
cd ..
# ${testProgram} --gtest_output=xml:${gTestXML}
# --gtest_filter=*init_getMsg_MSG_SUCCESS_PHONE_PKT_EVT_PHONE_NOTIFY_PKT_REGISTERED*
#--gtest_filter=*init_getMsg_MSG_FAILURE*
#--gtest_filter=*init_getMsg_MSG_SUCCESS_PHONE_PKT_EVT_PHONE_NOTIFY_PKT_REGISTERED*
# check test if run failed
#if [ $? -eq 0 ]; then
# echo " === '${project}' run unit test '${testProgram}' succeed ==="
#else
# echo " === '${project}' unit test '${testProgram}' failed ==="
# exit 1
#fi
cd ${gTestResultFolder}
cp $(find ${build_unittest_xxx} -type f -name "*.gcno") ./
cp $(find ${build_unittest_xxx} -type f -name "*.gcda") ./
#lcov -d . -t result_ut -o result_ut.info -b . -c --rc lcov_branch_coverage=1
#genhtml --branch-coverage -o result_html result_ut.info
lcov -d . -t result_ut -o result_ut.info -b . -c --rc lcov_branch_coverage=1
#lcov -d /home/uidp3659/gmock.py/__C_Toyota/CMakeFiles/center_comm_mgr.dir/ -t result_ut -o result_ut.info -b . -c --rc lcov_branch_coverage=1
lcov --remove result_ut.info '*/usr/include/*' '*googletest*' 'Mock*' 'UT*' '*aivc-macchina/platform/*' --output-file result_ut.final --rc lcov_branch_coverage=1
genhtml --branch-coverage -o coverage_html result_ut.final -p "${LCOV_PREFIX_DIR}"
echo "google test coverage result output to '${gTestResultFolder}/result_html/index.html'"
exit 0;
다 돌리면 Windows 환경이든 Linux 환경이든 다음과 같은 두 종류의 리포트를 생성할 수 있다.
두 개를 하나로 통합할 수 있으면 좋겠지만 시간도 없고 이정도면 충분하다는 매니저의 판단으로 여기서 내 첫번째 업무는 마무리되었다.
업무를 수행하면서 윈도우 프롬프트, 리눅스 쉘 스크립트 명령어에 대해 조금이나마 배울 수 있는 계기가 되었다.
CMake와 컴파일러에 대한 개념도 조금 더 명확해졌고, CMakeLists.txt를 활용해서 Makefile을 생성하는 방법도 배웠다.
파이썬으로 정보를 파싱해서 리포트를 생성해본 경험 역시 재밌었다. 윈도우 lcov 리포트 분석하면서 perl 에 대해서도 조금 맛볼 수 있었다.
여러모로 나에게도 재미난 경험이였다.
'개인 > 싱가포르' 카테고리의 다른 글
싱가포르 출장 첫 번째 업무 (2) (0) | 2019.11.26 |
---|---|
싱가포르 출장 첫 번째 업무 (1) (0) | 2019.11.26 |