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

25,086 views

Published on

Published in: Technology
4 Comments
64 Likes
Statistics
Notes
  • 국가별 관리는 ifdef같은거 쓰지말고 그냥 하드코딩하거나 xml같은걸로 스크립트 만들어 관리하는게 낫지 않나
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • ifdef는 안쓸수 있으면 안쓰는게 좋죠. 이벤트는 그냥 따로 관리하는 함수같은걸 두는게 좋을 듯.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 으음... 맞는 말이긴 한데, 정말 ifdef를 이용하는 것 밖에 방법이 없는지는 좀 고민이 필요한듯 한데요?
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 옳은소리인데... 다들 실천을 해야지..
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
25,086
On SlideShare
0
From Embeds
0
Number of Embeds
195
Actions
Shares
0
Downloads
136
Comments
4
Likes
64
Embeds 0
No embeds

No notes for slide

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

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

×