본문 바로가기

개인/싱가포르

싱가포르 출장 첫 번째 업무 (3)

막상 윈도우용으로 생성한 첫 번째 배치 파일을 리눅스에 적용하려고 하니 문제가 많았다.

하긴 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