재컴파일 속도 올리기

2009/03/25 22:45
사실 나는 컴파일이 느려서 불만이었던적은 거의 없는데 make 파일을 작성하다가 (재)컴파일 속도를 올리는 방법을 컴파일러 입장에서 생각해보게 되었다.

컴파일을 할때 .o를 새로 만들필요가 없으면 컴파일 안하는게 가장 빠른 방법일것이다. 그래서 make는 target과 src의 업데이트를 비교해 src 파일이 업데이트가 없으면 컴파일을 수행하지 않는다.(make와 그 친구들 참조)

근데 이 작업에 의외의 난관이 있는게, c에서 include 하고 있는 헤더가 변경되면 어떻게 될것인가 여부다. 즉, c파일이 변경되었는지 아닌지를 판별하기 위해서는 .c파일과 .o 파일의 시간확인만으로는 안되고 .c파일이 의존하고 있는 .h파일들과 .o 파일의 시간확인이 필요하다.

.c파일이 include하고 있는 헤더를 확인하기위해 많이 쓰는방법이 makedep같은 의존성 확인툴을 사용하는것이다. 또 다른방법으로는 gcc -M 옵션으로 include되는 의존성을 확인하는 방법이 있다. 의존성을 확인할때는 #ifdef 같은것으로 include가 제한될수 있으므로 플래그 옵션까지 넣어서 확인하는게 일반적이다.

만일 헤더가 다른 헤더를 include하고 있다면 다시 그 include하고 있는 파일까지 일일이 .o파일과 비교해봐야 할것이다. 만일 그렇게 하지 않으려면 의존성 확인은 .c파일의 헤더만 확인하고 대신에 .c파일에서는 모든 헤더를 다 써주겠다는 프로젝트 고유의 룰을 만들고 그것을 바탕으로 make 파일을 작성해 주어야 할것이다.(gcc를 사용하면 소스파일만 적어넣어주면 .c파일과 .o 파일에 관련된 모든 종속파일들을 다 보여준다. 만일 gcc -MM 옵션을 주면 시스템 헤더등은 제외한다.)

비주얼 스튜디오를 사용하면 이런 세세한 설정을 할 수는 없지만 이녀석도 사람이 만든이상 비슷한 일을 할 것이다. 잘 알려진 좀더 나은 방법으로 삼바 프로젝트에서 한것처럼 변경사항관리같은것을 해슁해서 캐싱하고 있다가 그것을 토대로 변경사항을 확인하는 방법등이 있으니 그것을 사용하고 있을지도 모르겠다.(모르긴 몰라도 이런식의 방법이 아니면 비주얼 스튜디오가 F5를 눌렀을때 번개같이 실행하는것은 납득할수 없다. 일단 변경된지를 체크해야 하는데 그것이 위에서 말한것처럼 쉽지 않기 때문이다.)

어쨌거나 이렇게 복잡하게 얽긴 헤더는 확실히 컴파일 속도를 느리게 하는 원인이다. 복잡하게 얽힌 의존성을 확인하는데 걸린 시간이 그냥 컴파일을 하는데 걸린 시간과 비슷해질지도 모를일이다. 그래서 우선 컴파일 속도를 빠르게 하려면 헤더 종속성 문제를 코딩단계에서 고려해야 한다.

만일 .o 파일이 아닌 .a 파일(즉, 라이브러리로) 만든다면, include 의존성을 확인할 필요가 없이 .a 파일과 관련된 모든 파일들과 .a 파일의 업데이트 시간만을 비교하는것으로 재컴파일을 할지를 결정할수 있다. 내가 이 방법을 써봤는데 확실한 속도 향상이 있었다.

그래서 라이브러리를 만들어내는 중간 프로젝트들을 많이 만들어 배치하는것이 전체적인 컴파일 속도를 올리는 또 다른 방법이 될 수 있다.

이런식의 테크닉들을 적용하려고 보면 makefile을 작성하는것이 정말 아스트랄해진다. 그래서 내가 선택한것은 rake였는데 굉장히 만족하면서 사용하고 있다.

아래는 앞에서 말한 로직을 만족하는 rakefile 내 함수의 일부이다.
(Language : perl)
i = 0
size = files_to_check.length
while i < size
    break unless uptodate?(target, files_to_check[i])
    i += 1
end

# do not need build
return if i == size

# need to compile
updated_objects = 0
srcs.each do | fullPath |
    #puts fullPath
    gcc_mm = "gcc -MM #{include_flags} #{fullPath}"
    result = `#{gcc_mm}`.split
    object_file = result[0].chomp(':')
    object_file.gsub!(/\.o$/, '_g.o') if @with_debug_symbol
    need_compile = uptodate?(object_file, fullPath) ? false : true
    unless need_compile
        2.upto(result.length-1) do | result_index |
            dependent_header = result[result_index]
            #puts dependent_file
            if ( dependent_header != "\\" ) \
                and ( dependent_header.include?("wxWidgets-2.8.9") == false ) \
                and ( dependent_header.include?("/usr/") == false ) \
                and ( uptodate?(object_file, dependent_header) == false )
                puts "#{object_file} will be recompiled because #{dependent_header} was changed"
                need_compile = true
            end
            break if need_compile
        end
    end
    #compile
    if need_compile
        compiler = ( fullPath.match(/.*\.cpp$/) != nil )? 'g++' : 'gcc'
        compiler << " -g -o #{object_file}" if @with_debug_symbol
        sh "#{compiler}#{include_flags} -O3 -c #{fullPath}"
    end

    lib_flags_head << ' ' + object_file
    updated_objects += 1 unless uptodate?(target, object_file)
end

전체 소스는 여기서 볼수 있다. .h와 .c 파일의 의존성은 는 gcc( -MM옵션)를 이용해 파악하고 있다. uptodate? 라는 함수가 파일간의 timestamp를 확인하는 함수이다. .a를 빌드해내는 프로젝트라면 앞에서 말한것처럼 files_to_check 라는 배열에 .a를 만드는데 관여하는 모든 파일을 넣고 그것들의 변경여부를 확인한다.

rake로 만들어 생기는 다른 장점으로는 Hudson에 연동하기가 매우 쉽다는 점이다. 내가 Hudson에 rake 작업들을 등록하고 맨 처음에 해본일이 과연 내가만든 빌드규칙과 MS의 빌드 규칙중 누가더 빠른지를 확인하는거였는데, 물론 clean상태의 컴파일 속도가 아니라 변경사항이 일부 있을때의 재컴파일 속도이다.

hudson_rake_build

위의 스샷처럼 루비 Rake를 통해 직접 작성한 gcc_debug 가 동일한 조건에서 msbuild를 이용하여 컴파일한 vc_debug 보다 6배 이상 빠르다! 흐흐.

-_- 세줄요약
1. 헤더 종속성을 고려하자
2. 라이브러리 프로젝트를 잘 활용하자.
3. rake 만세.

프로그래밍 Development, rake, 루비, 빌드

vim tips : 두개의 file을 diff 하는 방법

2008/11/13 22:20
비교하고 싶은 두 파일이 있을때 vim을 이용하면 편리하다.

간단히 두 파일을 하나의 vim으로 열면 vim 하나에 두개의 버퍼가 있을것이다. 현재 vim에 어떤파일들이 열려있어서 어떤 버퍼들이 있는지를 보려면
:buffers
라는 명령을 치면 된다.

그러면 불친절한(?) 리스트가 뜨는데, 리스트에 나타난 기호와 알파벳의 정체는 이렇다.
  • % current window
  • # alternate buffer (switch using :e# or :b#)
  • a active (loaded and visible)
  • + modified

그 리스트 중에서 현재 편집중인 것과 diff하려는 버퍼를 split 하여 열면 된다.
:sb N
여기서 N은 리스트에 나타난 버퍼번호이다. 나는 diff를 할때 비교하려는 파일을 수직으로 나누어 보는것을 좋아하므로 버퍼를 항상 수직으로 연다.
:vert sb N
ctrl+W, W를 누르면 분할된 창끼리 넘나드는데 넘나들면서 각각의 버퍼에 diffthis명령을 준다.
:diffthis
그러면 두개의 창이 diff 모드가 된다. 만일 diff모드를 해제하고 싶다면 diffoff( 7.0이상이던가.. 그렇다)를 준다.
:diffoff

reference link
   - :buffers 명령시에 나타난 불친절한 메시지를 친절히 설명해 놓은 사이트
   - vimdiff의 더 많은 활용 from kldp

멀티플랫폼/개발환경 Development, vim

vim tips : 현재 편집중인 파일이름관련

2008/10/30 11:21
얼마전 회사동료분께서 notepad++ 의 'Current dir path to Clipboard' 기능이 파일 편집에 있어서 매우 유용하다라 요지의 말을 했었었다(-_- 한 1년전쯤?) 그리고 친구녀석이 vim에서 같은 기능을 찾았었던것 같다. 요새 Portable Apps 로 컴퓨터 사용환경을 바꾸면서 vim을 꾸미다가 생각이나서 관련자료들을 찾아보았다.

우선 vim에서 현재 편집중인 파일 - 버퍼 - 는 expand("%")라는 표현식을 통해서 문자열로 얻을수 있다. 예를들면, vim으로 문서를 열고
:echo expand("%")
라는 명령을 치면 커맨드라인에 현재 편집중인 버퍼의 이름이 출력된다.

둘째로, vim에는 'yank'등을 위한 register라는 특수한 변수들이 있다. 이러한 변수들은 @를 사용하여 vim script등에 사용할수 있다. 예를들면 제일만만한 이름없는 레지스터 "에 "hi"라는 값을 집어넣어서 p 단축키를 통해 "hi"를 붙여넣으려면
:let @" = "hi"
라고 커맨드 라인에서 입력하고 편집모드에서 p를 누르면 원하는대로 hi가 붙여넣어질 것이다. (좀더 자세한 사항은 :help let-@) 특별히, win32계열의 gvim에서 @* 는 윈도우 전역 클립보드를 의미한다.

마지막으로 substitute라는 vim 내장함수가 있는데, 이것은 정규표현식을 이용하여 vim script의 문자변수를 치환해준다. 예를들면 현재 편집중인 버퍼이름으로부터 디렉토리 패쓰만을 뽑아오려면
substitute( expand("%"), '\(.*\\\)\(\).*', '\1', 'g' )
와 같이 사용하면 된다. (이 정규표현식에 대한 좋은 설명을 http://www.kldp.org/node/91397 에서 볼수 있다.)

이 세가지 팁들을 합쳐서
:let @*= substitute( expand("%"), '\(.*\\\)\(\).*', '\1', 'g' )
를 입력해주면 현재 편집중인 버퍼의 디렉토리 패쓰가 윈도우 클립보드에 저장되며, ctrl+v 등을 이용하여 붙여넣기 할수 있다. 만일 자주사용된다면 키맵을 하거나 메뉴를 편집하여 추가하면 될것이다.

멀티플랫폼/개발환경 Development, vim

Designing Interfaces

2007/11/16 00:44
Go to online bookstore ISBN:0596008031
학교 HCI 부교재. 인터페이스를 몇가지 패턴으로 분류하여 제시하고 있다. 책의 구성이나 내용이 무척 훌륭하다.

책은 디자인이 필요한 요소들을 크게 Organizing the content / Getting arround / Organizing the page / Doing things / Showing complex data / Getting input from users / Builders and editors / Making it look good 으로 나누고 각 분류별의 세부 패턴을 what / use when / why / how / example 등으로 자세히 기술하고 있다.

(내가 알지 못한채) 제일 많이 쓰는 몇가지 패턴들을 뽑아보면
  • One-Window Drilldown
  • Global Navigation
  • Hub and spoke
  • Breadcrumbs
등이 있는데, 내가 HCI 시간에 하고 있는 텀프로젝트도 저 패턴들을 사용한다.

패턴 분류의 가장 큰 장점이라면 대체 패턴이나 관련 패턴들의 소개인데, 이책도 마찬가지로 구성되어 있다. 예를들면, One-Window Drilldown이 Multiple windows / Tiled Panes / One-window paging 중 One-window paging 을 구현한것이라고 소개하고 있고, 관련된 패턴으로 Global Navigation이나 Hub and spoke를 설명하는 식이다. 이렇게 연결된 패턴들은, UI를 구상할때 정말 큰 도움이 된다.

웹사이트에서도 쉽게 패턴들을 찾아볼수 있게 되어있다.( 책의 전체내용이 나와있지는 않다.) 강력추천!

프로그래밍 Development, , 학교수업

make와 그 친구들

2007/09/25 23:00
make를 무지무지 싫어했다. 알수없는 매크로로 덕지덕지 붙어 있는것도 그렇고 탭들여쓰기도 그렇고.. 그런데 그간 내가 make에 대해 오해하고 있었나보다. 나는 make를 '변경에 관한 관리툴'로 보지 않고 스크립트언어의 일종으로 본것이다.

make는 빌드 관리 시스템이다. 빌드 관리에서 가장중요한것은 변경에한 관리다. 종속성관리라는 요소도 사실은 변경사항을 적용하기위한 하나의 부가적인 측면에 지나지 않는다. 그래서 make는 변경사항 감시와 변경에 대해, 종속적인 순서에 의거 정해진 일을 해주는 시스템툴이라고 요약할수 있겠다.

make의 기본적인 항목들을 살펴보면 다음과 같다.

1. 매크로 정의
매크로는 다음과 같이 정의할 수 있다.
#재귀적 확장 매크로, 뒤에서 $(VALUE)를 통해 재작성하면 그것도 여기에 적용된다.
VALUE = something

#단순확장 매크로, 이후의 $(VALUE)를 단순히 something으로 치환한다.
VALUE := something

#기존의 매크로에 something을 공백을 두고 덧붙있다.
#ex. 기존 VALUE가 anything 이었다면, 이후 anything something 이 된다.
VALUE += something

#앞에 VALUE가 정의 되어 있지 않다면 VALUE를 정의하고 값을 something이 되게 한다.
VALUE ?= someting

#make 함수를 사용하였다면 그 결과로 치환된다.
VALUE = ($shell pwd)
그리고 다음과 같이 사용한다.
all:
#반드시 탭
    @echo $(VALUE)

2. 타겟의 기술
타겟은 아래와 같이 기술된다.
target : dependency1 dependency2
<tab>command
타겟은 종속적인것을 먼저 수행하고 타겟의 커맨드를 수행한다. 만일 이때 타겟과 종속적인것이 오브젝트 파일이나 소스파일이라면, 변경사항을 검사하고 확장자 규칙에 자동적으로 종속작업을 할수 있다.

3. 구문 / 함수
make는 여러함수와 간단한 구문을 포함한다. 조건 구문을 먼저 살피면
#아래의 구문은 명령에 들어가며 매크로의 값을 비교해서 명령을 수행한다.
all :
ifeq( &(CC), gcc )
    @echo "Complier - GCC"
else
    @echo "Complier - Not GCC"
endif

#아래의 구문은 매크로 정의에 따라 타겟을 구성하거나 구성하지 않는다.
ifndef DEF_ONLY_ONE_FILE
#SRCS:.c = .o는 SRCS의 .c 부분을 .o로 바꾸는 make 함수이다
$(TARGET).o : $(SRCS:.c = .o)
# $@은 타켓을 의미하며 $^은 종속성을 의미하는 내부지정 매크로다.
    $(LD) -r $^ -o $@
endif
그리고 make는 매크로(문자변수 정도로 생각하면 편할듯)를 편리하게 다룰수 있는 많은 함수들도 제공한다.
#shell함수, 함수뒤에 오는 쉘 명령을 수행하고 결과를 문자열로 던저준다.
PWD := $(shell pwd)

#wildcard 함수, 지정된 디렉토리에서 패턴과 일치하는 파일리스트를 뽑는다.
#디렉토리를 특별히 지정하지 않으면 .와 같다.
#patsubst, $(매크로명:패턴 = 치환할 문자열
SRCS = $(wildcard *.c) #$(wildcard ./*.c와 같다)
OBJECTS = $(SRCS:.c = .o)

#foreach 함수 : $(foreach 변수명, 대입문자열, 확장문자일)
#아래는 현재 디렉토리에서 시작해서
#dir_sub_1과 dir_sub_2 아래에 있는 모든 .c 파일을 SRCS로 만든다.
#먼저 dir이라는 변수명에 . 이 들어가서 $(wildcard ./*.c)가 수행된다.
#만일 현재에 a.c 가 있고 dir_sub_1에 b.c 가 있고 dir_sub_2에 c.c가 있다면
#SRCS 는 ./a.c dir_sub_1/b.c dir_sub_2/c.c 가 있다.
SRCS := $(foreach dir, . dir_sub_1 dir_sub_2, $(wildcard $(dir)/*.c) )

4. 기타 규칙
make의 다른 규칙들을 살펴보려면 'make -p' 명령을 통해 현재 규칙들을 살펴볼 수 있다. 만일 이 명령을 수행한 디렉토리 내에 makefile이 있다면 그 makefile에 대한 매크로와 규칙들을 화면에 출력해줄 것이다.

5. make의 친구들
사실 make는 변경사항을 종속성에 따라 감시하는것을 제외하고는 스크립트로써 꽝이다. (100줄만 넘어가도 정말 내가 뭘 짜고 있는지 모르겠다.) 그런 사람들이 많았는지 makefile 작성을 도와주는 많은 유틸리티 프로그램이 있다. 그중에서 대표적인것이 autoconf와 automake 인데, autoconf는 configure.ac 와 Makefile.in을 가지고 configure 스크립트파일을 만들어 내고 사용자는 이 configure 스크립트 파일을 이용해서 makefile을 생성해 내도록 하는 도구이다. automake는 Makefile.in을 쉽게 만들수 있도록 도와주는 유틸리티다. 사실 이 도구들은 사용하기 조금 까다로와서 KDE같은 경우에는 cmake를 사용하게 전환했다는 소리를 들었다. 음... 요는 makefile을 만들면 되는것 아닌가? 그렇다면 ruby같은 스크립트를 이용하는것도 괜찮을 것이다. 사실 KDevelop을 사용하면 이런 configure.ac 파일같은것들을 쉽게 작성할수 있도록 도와주기때문에 그럭저럭 괜찮고, 또 configure 스크립트가 거의 표준이기때문에 쉽게 떨쳐 내지는 못하겠지만...

멀티플랫폼/개발환경 Development

재사용성과 결합도 줄이기

2007/08/12 22:12
아래의 글은 pokiwiki에 적었던 글인데, 위키를 정리하면서 이곳으로 옮겼습니다.
꽤 오래전에 적은 글인데, 처음 C++ 배울때의 진지함(?)과 풋풋함이 있네요 =_=

1. 재사용성
소프트웨어 개발에 있어서의 재사용성에 대한 문서입니다.
재사용이 용이한 코드라는것은 어떤 '박스'를 경계로 이 박스를(좀더 잘 만들어진 다른박스와) 교체하기 쉬운 코드라는 의미입니다. 이러한 박스는 크게 블랙박스와 화이트박스가 존재하며, 각각의 박스는 서로다른 특징을 가집니다.

=== 블랙박스 모델 ===
 경계를 통과하는 값(파라미터,setter, etc..)만 알면 되므로 화이트박스 모델보다 독립적이고 모듈적이며, 박스의 관리가 쉬운 모델이나, 사용에 있어서 유연성이 부족하다는것이 치명적인 단점입니다. C++에서의 함수를 통해 이러한 블랙박스 모델을 구현할 수 있으며, 함수의 local변수보다 생명주기가 훨씬 긴 멤버변수를 가진 클래스를 통해서도 블랙박스 모델을 구현할 수 있습니다.. 클래스를 통한 블랙박스 모델의 대표적인 사용이 set and construct 기법이며, END프로젝트에서도 이러한 기법을 자주 이용합니다.

=== 화이트박스 모델 ===
 보통 클래스의 파생을 통해서 구현되며, MFC등에서 흔히 사용하는 '유도하는 아키텍쳐 디자인'에서 많이 쓰입니다. 화이트박스를 잘 사용하기 위해서는 투명한 박스 내부를 잘 알아야 하기 때문에 블랙박스 모델보다 사용하기는 어려우나, 확장 가능한 아키텍쳐를 디자인 하는데 있어서는 필수입니다. 화이트박스 모델을 디자인하는데 있어서는 교체가능한 부분과 서로 약속된 부분을 잘 구분하여 디자인하는것이 중요하며, 디자인패턴은 이러한 디자인에 있어서 큰 도움이 될 수 있습니다.

2. 결합도 줄이기
실용주의 프로그래머의 결합도 줄이기와 디미터 법칙이나 EffectiveC++중에서 4장, 설계 및 선언을 읽으면서 클래스내의 멤버함수에 대한 생각들에 관한 글

== 멤버함수와 변수(멤버변수 혹은 인자)의 결합도 ==
결합도 줄이기에서 중요한 것은 쓸대없는것을 넘겨서 함수가 그것과 결합되는것을 막자는 것이다. 그런데, 메쏘드들을 짜다보면, 이것들이 멤버들을 건들때는 자연히 함수의 인자값으로 넘기지 조차 않는다. 함수의 인자값을 보고 이 함수가 어떤것들과 결합되어 있는지, 어떤 의미를 갖는지를 알수 있는 함수가 좋은 함수다. 그러나 클래스들을 많이 쓰면서 이렇게 인자를 넘기는 경우가 작아졌다. - 사실 객체지향의 장점중의 하나가 이런 과도한 함수인자를 막는데 있는것이지만...

따라서, 어떤 함수가 어떤 멤버와 결합되었는지 정확하게 알릴 필요가 있다. 그것은 인자를 통해서도 알릴수 있지만, 함수를 멤버 변화에 종속시키도록 세부화 함으로써도 가능하다. 거대한 함수는 환영받지 못한다.

함수명을 동사-영향받는 객체 형식으로 짓는것도, 영향받는것을 명시하기 위해서 일것이다.

강한결합을 가진 함수가 나쁘다고 생각하지 않는다. 그러나 '''결합이 명확하게 명시되지 않는 함수'''는 나쁘다.

== 멤버함수와 멤버함수간의 흐름의 결합도 ==
중요하지만 간혹 생각하지 않는게 이 '''함수간의 결합도'''이다. 거대 함수를 쪼개다 보면, 반드시 묶여야 되는 함수가 생길 수 있다. 그러나 이런 경우를 문법적으로 명시하기란 어렵다. 예를들면, 로딩되는 것들의 종류에 따라 UI의 모양이 변해야 되는것을 요구사항으로 가진 프로그램을 생각해보자. 이것을 구현하기 위해 로딩을 하는 함수와 UI의 모양을 변하는 함수 2개를 준비했고 로딩이 되면 어떻게 변해라는 변수를 바꾼다고 생각하면, 이 2개의 함수는 꼭 딸아 다녀야 한다. 그러나, 로딩을 하는 함수가 여러벌이라면 1:1이 아닌 n:1 결합이 되어서 한 함수로 묶기도 난감하고 또, 앞에서 말한 결합이 명확하지 않는 거대함수가 될 수 있다. 이런 흐름이 결합된 함수들끼리는 같은 클래스에 넣고 이것이 아주 클 경우에 다른 객체로 쪼개는것을 고려해 봐야 할 것이다. 한 클래스에는 이러한 큰 흐름이 3개 안으로 들게 설계해 보자.

프로그래밍 Development, 소프트웨어공학

wxWidgets 과 윈폼, 그리고 UI 개발툴

2006/09/17 23:15
wxWidgets을 이리저리 건들건들 해보았었다. 상당히 거대하고 커뮤니티도 잘 되어있는데다가 모양도 이쁘다. 또한 익숙한 MFC와도 비슷하다. 이리저리해서 이걸 비주얼스튜디오 익스프레스에서 이걸 GUI로 쓰려고 했는데, 생각보다 설정이 많이 복잡하다. 특히 wxAUI 나 wxIFM 같은것을 쓰려면 rc파일을 이리저리 건들어주어야할 일이 많은데, 리소스에디터를 vs express에서 지원해주지 않다보니 삽질을 좀 해야한다.

삽질에 지쳐 기분전환겸 윈폼을 살펴봤는데, 호.. 잘 갖추어 놓았다. 그러나 역시 표준 c++이 아닌 MS식 C++(C++/CLR 이던가?)이라서 접었다. 익숙하지 않더라.

리소스 편집기가 없으니까 생각보다 불편하다. 훌륭한 컨트롤러란 리소스 편집기로 자리잡아놓은것을(DDX등으로 이어준다) 셀프드로잉으로 자기모습으로 바꾸고 컨트롤러 세팅은 자료주도적으로 하는것들이라고 생각한다. FooButton 이나 어딘가에서 주서와서 맵정보보기에 쓰고있는 DIB 컨트롤러들이 이런식이다. 여기서 리소스 편집기가 담당하는 자리잡음을 눈으로 볼수 있게 해주는 기능이 편리함을 느끼게 하는데 적지않은 비중을 차지한다.

자바의 레이아웃 철학은 훌륭한것 같지만, 막상 내가 자바로 만든 UI프로그램들은 모두 null layout을 사용했던것 같다. 물론 창은 크기 조절 못하게 해놓고...

좀더 나은 UI 프로그램을 개발하기 위해서는 컨테이너는 동적으로 변할 수 있도록 코딩위주로 하고 컨테이너에 직접적인 컨트롤 배치는 리소스 에디터같은 디자이너를 사용하는것이 올바른 방향인것 같다.

프로그래밍 Development

MDI 의 종말?

2006/08/03 22:22
최근 많이 쓰는 프로그램들은 MDI를 거의 안쓰는것 같다.
대신에 Splitter Window 라든지 Dockable 윈도우를 쓰는것 같다.

UI에 대한 SWT의 재해석은 놀랍다. 이제 도큐먼트대신에 워크벤치와 사이드바개념은 널리 익숙하다. 사실 MS제품들도 보면 이런 UI다. 윈도우 탐색기나 Visual Studio 등등..

UI를 만든다면, 따라서 윈도우-워크벤치-바 개념으로 접근하여 설계하는게 좋을것 같다. 워크벤치는 탭이 가능한 윈도우가 좋을것이다. 바는 기능에 따라서 지네들끼리 동적으로 나누어 질 수도 있을것이다. 그러나 바에 과도한 자유를 주는것은 위크벤치상의 일을 익숙하게 만드는데 어렵게 할 수 있는 요인이 될수도 있다. 그런면에서 파이어폭스의 고정적 사이드바와 하단의 동적 도구바는 상당한 일관성을 지녀 익숙해지기 쉽다.

최근의 KDE프로그램들의 UI도 관심을 가질만하다. 이들은 전통적으로 MDI가 적었고 DialogBar와 같은 Dockable Window가 많았다. QT를 배워보는것도 UI 공부를 하는데 좋은 일일 것이다.

윈도우/개발환경 Development, MFC, 주저리

성의있게 프로토타입 만들기

2006/07/22 21:21
프로토 타입을 만들때는 성의 있게 만들 필요가 있다.
대충 '이렇게 하면 되겠지' 같은 프로토타입을 설정하고 작업을 하는것은 Scaffolding에 어울리며 좀더 큰 규모의 작업에는 성의있는 프로토타입이 필수이다.

성의있는 프로토타입을 만들기 위해서는
1. 데모화면
2. (작동)시나리오
3. Spec
을 모두 작성해야한다.

이러한 프로토타입은 작성이 어렵기 때문에 보다 쉬운 Scaffolding과 연계하며 프로젝트를 진행하는것이 좋으며, 공부목적이 아니라 프로젝트를 완성하려면 성의있는 프로토타입작성이 반드시 필요하다.

프로그래밍 Development

find / perl / grep

2006/07/14 10:27
perl -pi -e 's/index\.html/main\.html/g' *
전체 파일에 대해 index.html 이라는 문자열을 main.html 이라는 문자열로 바꾸기

find 옵션
atime(access time) / ctime(change time)
type : 파일 타입 옵션 (f : file / d : directory)
-exec 명령어 {} \; : 지정한 명령 적용. {} \; 에 주의할 것
ex. find . -name '*.txt' -exec perl -pi -e 's/바뀌기이전/바뀐이후/g' {} \;

grep
현재폴더 이하에서 alc를 포함한 것을 번호를 나타내어 출력
grep "alc" * -R -n

http://linuxer.mireene.com/bbs/view.php?id=tips&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=40

멀티플랫폼/실행환경 Development, linux