Your SlideShare is downloading. ×
자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012

21,700
views

Published on

Published in: Technology

2 Comments
50 Likes
Statistics
Notes
No Downloads
Views
Total Views
21,700
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
109
Comments
2
Likes
50
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 자동화된 소스 분석, 처리, 검증을 통한소스의 불필요한 #if - #endif 제거하기김이선veblush@[nexon|gmail]
  • 2. 버블파이터 BNB 카트라이더 프로토타입 에버플래닛 던전엔파이터 GTR프로그래머 리드 프로그래머 리드 프로그래머 리드 프로그래머 테크니컬 디렉터 프로그래머 게임 프로그래밍 11년차
  • 3. 프로젝트 소스 코드의유지보수성 (Maintainability) 관리가 중요!
  • 4. [던전엔 파이터] 에서 했던 코드 관리 중 하나인불필요한 #if - #endif 제거 작업
  • 5. 도입 결과 결론 분석 처리 검증
  • 6. 오늘 알아볼 코드[던전엔 파이터]
  • 7. “퀘스트 시스템” 추가 작업
  • 8. Flags.h 1단계 // 김철수: 퀘스트 시스템 구현플래그 정의 //#define _QUEST_SYSTEM
  • 9. * #ifdef _QUEST_SYSTEM ui.questWnd.setButton(…); 2단계 ui.questWnd.setEvent(…);기능 구현 #else ui.questWnd.setDisable(); #endif
  • 10. Flags.h 3단계 // 김철수: 퀘스트 시스템 구현기능 플래그 켬 #define _QUEST_SYSTEM
  • 11. 작업 중인 코드가 다른 작업자, 라이브 코드에 영향을 주지 않음(장기간 작업, 빠른 롤백, 이벤트)
  • 12. 국가별 소스 코드 공유에 도움 (국가별 플래그, …)
  • 13. 간단한 작업 방식(교육 비용이 낮음)
  • 14. 플래그 켬/끔이 Rebuild 를 초래(Flags.h 파일을 모든 파일이 #include 하므로)
  • 15. 코드가 점차 읽기 어렵고 수정하기 어려워짐(#ifdef - #endif 블록이 코드에 가득 차기 시작함)
  • 16. 코드가 점차 읽기 어렵고 수정하기 어려워짐(#ifdef - #endif 블록이 코드에 가득 차기 시작함)
  • 17. 죽은 코드가 생겨남(꺼진 플래그나 #else 에 묶엔 코드들)
  • 18. 그럼 플래그가 얼마나?
  • 19. 5400 개+1500 /1yr 2015 년 10000 개
  • 20. 플래그 개수가 늘어남에 따라 발생하는 추가적인 문제!
  • 21. #ifdef _EVENT_2006 ui.notice.setText(“월드컵 이벤트!”); 문제 1 ui.notice.setVisible(1);죽은 코드 ui.notice.setEventHandler(…); #endif
  • 22. #ifdef _NEW_UI_COMPONENT ui.notice.setText(“…”); ui.notice.setVisible(1); 문제 2 #else중복 코드 set(UI_NOTICE, TEXT, “…”); set(UI_NOTICE, VISIBLE, 1); #endif
  • 23. 플래그 작업 방식은 유지하되불필요하게 늘어난 플래그 개수를 줄여보자
  • 24. 불필요한 플래그 제거!
  • 25. #ifdef _QUEST_SYSTEM ui.quest.setVisible(1);플래그 켜서 제거 ui.quest.setEventHandler(…); #endif
  • 26. ui.quest.setVisible(1);플래그 켜서 제거 ui.quest.setEventHandler(…);
  • 27. #ifdef _EVENT_2006 ui.notice.setText(“월드컵 이벤트!”);플래그 꺼서 제거 ui.notice.setVisible(1); ui.notice.setEventHandler(…); #endif
  • 28. 플래그 꺼서 제거
  • 29. #define _NEW_QUEST #ifdef _NEW_QUEST # define _NEW_QUEST_FIX #endif플래그 병합 #ifdef _NEW_QUEST 제거 ui.event.setText(…); # ifdef _NEW_QUEST_FIX ui.event.setPos(…); # endif #endif
  • 30. #define _NEW_QUEST플래그 병합 #ifdef _NEW_QUEST 제거 ui.event.setText(…); ui.event.setPos(…); #endif
  • 31. 개운하다!
  • 32. 제거할 소스에서 테스트플래그 선택 플래그 제거
  • 33. 수천개를 수작업으로? Image: http://www.flickr.com/photos/15271532@N00/1172675049
  • 34. 리팩토링 딜레마! 실수하면? 누가하지?
  • 35. 자동화 Image: http://www.enggtechsolutions.com/?page_id=5
  • 36. 제거할 소스에서 테스트플래그 선택 플래그 제거 선택 제거 검증 자동화 자동화 자동화
  • 37. 도입 결과 결론 분석 처리 검증
  • 38. 플래그에 대한 정보 얻기(삭제할 플래그를 추리기 위해)
  • 39. 소스 파일
  • 40. #define F | #undef F#ifdef F | #ifndef F | #if defined(F)
  • 41. 국가별 Flags.h 파일에 정의된 플래그 추리기
  • 42. #define 뒤에 있는 주석도 가져오기
  • 43. Subversion Log
  • 44. 모든 커밋의 Rev#, 날짜, 작성자, 로그변경한 파일에 포함된 플래그 목록
  • 45. 사용: 날짜: 주석: 한국, 중국 2008-06-21 김철수, 퀘스트! _QUEST_SYSTEM플래그 정보 SVN: 파일: #29110, ironwater Interface/QuestWindow.h Interface/QuestWindow.cpp “[추가] 퀘스트 시스템 System/Quest.h 1차 작업” System/Quest.cpp
  • 46. 판단을 내릴 정보 가공!(단순한 정보 나열을 구체화)
  • 47. 플래그 정보 쿼리 결과 DB 테이블 쿼리 수행
  • 48. DB 를 통해 유연한 분석 가능
  • 49. 국가별 / 연도별 플래그 등장 표
  • 50. DB: 큰 그림 분석 시간별 증감 추이 국가별 사용 현황작업자별 플래그 추가 파일별 플래그 추이 플래그 영향력
  • 51. DB: 오류 분석 정의만 되고 사용되지 않음 (버려짐?) 정의는 없고 사용만 있음 (오타?) 정의가 여러 곳에 있음 (응?)정의가 여러 곳에 있으면서 값이 다름 (으악!)
  • 52. 모두 켜거나 끈 플래그 목록 추리기
  • 53. 모든 작성자 및 국가에서 상급자에게 피드백을 켜고 끈 삭제 리뷰 받아 진행플래그 수집 요청
  • 54. 도입 결과 결론 분석 처리 검증
  • 55. 제거할 플래그를 소스에서 제거
  • 56. #define _QUEST_SYSTEM // 퀘스트플래그 켜서 #ifdef _QUEST_SYSTEM 제거 ui.quest.appendMsg(“…”); questDlg.show(); #endif
  • 57. 플래그 켜서 제거 ui.quest.appendMsg(“…”); questDlg.show();
  • 58. #ifdef _EVENT_2008 // 2008 설 이벤트 ui.event.setText(…); ui.event.show();플래그 꺼서 #else 제거 ui.event.setVisible(0); #endif
  • 59. 플래그 꺼서 제거 ui.event.setVisible(0);
  • 60. #define _NEW_QUEST #ifdef _NEW_QUEST # define _NEW_QUEST_FIX #endif플래그 병합 #ifdef _NEW_QUEST 제거 ui.event.setText(…); # ifdef _NEW_QUEST_FIX ui.event.setPos(…); # endif #endif
  • 61. #define _NEW_QUEST플래그 병합 #ifdef _NEW_QUEST 제거 ui.event.setText(…); ui.event.setPos(…); #endif
  • 62. http://dotat.at/prog/unifdef
  • 63. Unifdef 가 기본적인 기능은 잘 해줌
  • 64. 다만 부분 평가는 해주지 않음#if defined(A) && defined(B) A=켬|끔 B=그냥둠 ↓ #if 1|0 && defined(B)
  • 65. 병합 제거는 따로 구현#ifdef A #ifdef A# ifdef A_fix… …# endif#endif #endif
  • 66. 작업 흐름 부분 평가원시소스 unifdef 결과소스 병합 제거 제거 플래그 리스트
  • 67. 도입 결과 결론 분석 처리 검증
  • 68. 원시소스 처리 결과소스원시EXE = 결과EXE
  • 69. 동일한 소스를 두 번 빌드 후 EXE 빌드시간, 디버그 정보 등이 EXE 에 포함
  • 70. 동일한 소스를 두 번 빌드 후 OBJ 디버그 정보가 OBJ 에 포함
  • 71. # name #1 .drectve #2 .debug$S #3 .text 비교할 때OBJ #4 .debug$S debug 섹션은 #5 .rdata 제외! #6 .text #7 .debug$S #8 .debug$T
  • 72. 원시소스 처리 결과소스원시OBJ = 결과OBJ
  • 73. 원시OBJ ≠ 결과OBJ DUMPBIN
  • 74. 같음원시소스 처리 비교 OK 다름
  • 75. 플래그 켬/끔 오류다른 함수 원인 파악 툴 버그 찾기 소스 문제
  • 76. 오류의 예#include “show.h”//#include “Flags.h”void show() {#ifdef _QUEST_SYSTEM ui.quest.print(…); ui.questDlg.show();#endif}
  • 77. __LINE__ ASSERT 매크로 등에 있음!검증 단계의 unifdef 는 행을 유지하도록. __TIME__ 작업 전에만 지웠다가 다시 살림.
  • 78. 도입 결과 결론 분석 처리 검증
  • 79. 제거 플래그 작업자의 처리 / 검증 / 커밋후보 선택 리뷰 자동화 자동화
  • 80. 작업자 리뷰에 시간이 들기 때문에리뷰 플래그 개수를 한번에 300~500 개로 유지
  • 81. 6 번의 플래그 제거 작업총 2,107 개의 플래그 제거
  • 82. 2,309 파일에서191,979 라인 제거
  • 83. 라인10% 코드 제거 90%
  • 84. 작성한 툴분석 Track 소스 & SVN 에서 정보 수집 Uniform Unifdef + 추가 소스 처리처리 CompareBin OBJ 파일 동일 검사검증 BatchRun 플래그 제거 및 검증을 일괄 실행
  • 85. 작성한 툴분석 Track 소스 & SVN 에서 정보 수집 Uniform 총 Unifdef + 추가 소스 처리 LOC:처리 CompareBin 1500 동일 검사 OBJ 파일검증 BatchRun 플래그 제거 및 검증을 일괄 실행
  • 86. 도입 결과 결론 분석 처리 검증
  • 87. 불필요한 #if - #endif 제거는소스 코드를 깔끔하게 유지하는데 도움!
  • 88. 소스의 유지보수성을 확보하는 작업을자동화 시키고 신뢰성 있게 만드는 것이 중요!
  • 89. 자동화된 솔루션은 반복해서 사용할 수 있어 계속해서 도움을 받을 수 있음!
  • 90. 분석은 처리 뿐 아니라 대상을 바라보는다른 관점을 제시하는 데에도 도움을 줌!
  • 91. 분석, 수행, 검증의 틀을코드 / 데이터를 개선하는데 사용해보자!
  • 92. 자동화된 Rename 리팩토링 ? 문제되는 소스에서 빌드이름 추리기 자동 변경 테스트
  • 93. 여러분들도!
  • 94. 감사합니다!