Author Archives: mix1009

컴퓨터 프로그래밍(CS) 인터넷 강좌

MIT OpenCourseWare 비디오와 오디오 강좌 – 컴퓨터 외에도 여러 공학 강좌가 있습니다. MIT OCW가 매스컴을 통해서 많이 알려졌지만, 비디오 강좌는 아직 많은 자료가 없는거 같네요. 이중 컴퓨터 강좌는:

  • 6.033 Computer Systems Engineering, Spring 2005
  • 6.046J / 18.410J Introduction to Algorithms (SMA 5503), Fall 2005

UC Berkeley 강좌 : CS뿐만 아니라 공학 강좌가 많이 있으며, 오른쪽에서 semester 선택하면 예전 강좌들을 들을수 있습니다. 현재 진행되고 있는 강좌도 들을수 있어서 좋네요.

  2007 Spring

  • CS 61A     The Structure and Interpretation of Computer Programs
  • CS 61BL    Data Structures and Programming Methodology
  • CS 61C     Machine Structures

  2006 Fall

  • CS 162     Operating Systems and Systems Programming
  • CS 61A     The Structure and Interpretation of Computer Programs
  • CS 61B     Data Structures
  • CS 61C     Machine Structures

  2006 Spring

  • CS 162     Operating Systems and System Programming
  • CS 252     Graduate Computer Architecture
  • CS 61A     The Structure and Interpretation of Computer Programs
  • CS 61B     Data Structures
  • CS 61C     Machine Structures

ArsDigita University CS 강좌 : 영국에 있는 대학인가봅니다. 저도 직접은 안봐서 모르겠지만… 다음 강좌들이 있네요.

  • Maths for Computer Science
  • Structure and Interpretation of Computer Programs
  • Discrete Maths
  • How Computers Work
  • Object-oriented Program Design
  • Algorithms
  • Systems
  • Web Applications
  • Theory of Computation
  • Artificial Intelligence
  • Unix Workshop
  • Database Management Systems
  • Applied Probability

University of Washington : 비디오 강좌만 정리된 페이지가 있는지 모르겠지만, 좋은 강좌가 많네요.

University of Indiana CS 강좌: 안타깝게도 비디오는 인증 절차를 통해서 받을수 있도록 바뀌었네요. 예전에는 볼수 있었거든요…

SICP (Structure and Interpretation of Computer Programs) – 1986년 오래된 강의이지만 저자 두명이 직접 설명합니다. 설명이 필요없는 유명한 책이고 여러 대학에서 교재로 사용하고 있습니다. LISP(Scheme) 언어로 강의가 이루어집니다.

http://video.s-inf.de/ : 독일의 대학인데 이 중에서 FP가 Haskell 언어로 강의입니다. 현재 서버에 접속이 불가능한데 구글 캐시에서 페이지 보고 다운로드하면 비디오는 다운로드 되네요. 그리고 다른 강좌는 모르겠지만 FP는 영어로 강의를 합니다.

그리고 강좌를 잘 정리한 글들입니다. 🙂

그리고 성격이 조금 틀리지만 윈도우즈 프로그래밍에 관심이 있다면 MS에서 제공하는 강좌도 도움이 될거 같네요.

trac 업그레이드 & plugin

trac 사용하면서 꼭 알아야할 사이트인 trac-hacks.org 에 대해서는 오래전부터 알고 있었지만 크게 필요가 없어서 플러그인은 사용하지 않았었습니다. 티켓에서 예상완료일자를 설정하려고 하니 달력에서 보고 설정할수 있으면 좋겠다는 생각이 들었습니다. 그래서 trac-hacks를 찾아보니 역시 플러그인 있네요 ^^. 물론 trac 자체에서도 custom field를 지원하지만, 달력에서 날짜를 고를수 있는 플러그인인 TracDatePlugin은 꼭 설치하고 싶더군요. 그런데 플러그인을 설치하려고 보니 0.9.X에서는 동작을 안한다고 하더군요. 그래서 업그레이드를 했습니다. 물론 일단 백업받고 시작했죠.

전에 사용하던 버전이 0.9.6이 였는데 FreeBSD ports를 통해서 0.10.4 버전으로 업그레이드했습니다.

# cd /usr/ports/www/trac
# make deinstall
# make install
# trac-admin /TRAC/PATH upgrade
# /usr/local/etc/rc.d/lighttpd restart

trac-admin 실행해주고 웹서버 재시작하니 업그레이드가 정상적으로 완료되었습니다.

trac plugin은 egg라고 zip 파일 형태의 패키지를 이용하도록 되어있습니다. python은 오래전부터 사용했지만, egg 패키지는 처음 사용해보는데 java의 jar 정도 되는거 같네요. 패키지의 종속성등의 메타 정보를 넣을수 있다고 합니다. 하지만, 소스에서 뭘 바꾸려해도 zip 안에 들어있어서 바로 편집하기 어려울듯하네요. Egg에 대한 자세한 내용은 여기를 참고하세요.

egg 파일은 단순히 py, pyc 파일등과 메타 정보를 압축한 zip 파일입니다. egg 파일을 만들기 위해서는 setuptools가 필요하다고 합니다. 역시 FreeBSD ports를 이용해 설치했습니다.

# cd /usr/ports/devel/py-setuptools
# make install

그리고 trac plugin 설명 페이지에서 설명한 대로 ez_setup을 설치했습니다.

# wget http://peak.telecommunity.com/dist/ez_setup.py
# python ez_setup.py

이렇게 하고 필요한 플러그인을 받고 egg 파일을 아래와 같이 만들면 됩니다.

$ unzip datefieldplugin.zip
$ cd datefieldplugin/0.10
$ python setup.py bdist_egg
$ cd dist
$ cp TracDateField-1.0.1-py2.4.egg /TRAC/PATH/plugins

플러그인 소스 받은후 압축풀고, setup.py를 찾아서 위처럼 실행해주면 dist 디렉토리 밑에 egg 파일이 만들어지고, 이 파일을 trac plugin 디렉토리에 옮겨주고 웹서버를 재시작하면 됩니다.

플러그인 중에 제가 사용중인 것 2개만 소개합니다.

TracWebAdmin 0.1.2dev-r4240 : trac-admin을 웹페이지를 통해서 할수 있도록 해주는 플러그인으로 trac을 개발한 edgewall에서 개발한 거고, trac 0.11에서부터는 기본으로 포함된다고 합니다. trac-admin 사용하면 이 정도 기능은 웹에서 가능해야한다고 생각했었는데, 꼭 설치해야할 필수 플러그인이네요.

TracDateField 1.0.1 : custom field에 날짜를 설정할수 있게 해줍니다. 아래와 같이 티켓 만들때 custom field로 date로 설정하면 달력을 보고 날짜를 설정할수 있습니다.


FreeBSD 쉘에서 색 사용

사용환경: FreeBSD 6.x, tcsh 또는 bash, 윈도우용 putty 터미널.

리눅스에 비해 FreeBSD를 사용하면 기본적으로 쉘상에서 색상이 거의 안나오는데, 몇가지 설정을 하면 리눅스 부럽지 않게 화려(?)해집니다.

tcsh 사용자는 .cshrc에 아래를 적당한 위치에 추가합니다.

setenv CLICOLOR
setenv LSCOLORS Exfxcxdxbxegedabagacad

set mch = `hostname -s`
alias prompt ‘set prompt = “%{\033[1;33m%}$mch%{\033[0m%}:%{\033[1;34m%}$cwd%{\033[0m%}> “‘

첫줄은 ls에서 기본적으로 색이 출력되도록 합니다. 두번째 줄은 폴더에 할당된 색이 기본적으로 파랑색인데 putty에서 파랑색이 눈에 잘 띄지 않아서 밝은 파랑으로 바꿔주었습니다. 자세한 것은 man ls

밑에서는 쉘 prompt에 색상이 출력되도록 했습니다. 색 지정은 이 페이지를 참조했습니다.

bash 사용자라면 .profile에 아래를 등록하세요.

export CLICOLOR=1
export LSCOLORS=Exfxcxdxbxegedabagacad
export PS1=”\[\033[1;33m\]\h\033[0m\]:\[\033[1;34m\]\w\]\033[0m\]> “

이렇게 하고 이전글에서 설명했던대로 .screenrc를 설정하면 아래와 같은 화면이 나옵니다:

플래시로 만든 마인드맵 서비스 comapping.com

개인적으로 mind mapping 프로그램을 유용하게 쓰고 있는데, 웹에서 플래시로 이렇게 잘 구현된 서비스가 있었다니 놀랍습니다. 한가지 아주 치명적인 문제를 빼면 돈을 내고 써도 아깝지 않을 서비스라는 생각이 드네요. 6개월에 $12 이라는 저렴한 가격 정책도 좋고, 협업툴로 활용할수 있어서 활용도도 높을것으로 생각됩니다. 치명적인 단점은 한글입력이 안된다는겁니다! 한글이 입력도 안되고, 복사해서 붙이기해도 안되네요.

요즘 플래시/FLEX/AIR 의 가능성에 대해서 흥미있게 지켜보고 있습니다. comapping 서비스가 플래시의 화려한 기능들을 잘 이용하고, UI도 너무 직관적으로 잘 만들었네요. “New Topic” 등에 마우스를 올리면 단순한 툴팁만 뜨는게 아니라 어디 항목이 생기는지까지 애니메이션으로 보여주는데 상당히 놀랐습니다. Tab을 누르면 포커스를 현재 선택된것으로 가져가주고 키보드만으로도 불편없이 사용할수 있도록 되어있습니다. 단축키는 FreeMind와 거의 똑같네요.

http://comapping.com
에 들어가시면, 가입 안하셔도 직접 사용해볼수 있습니다.

현재 회사에서는 CVS 디렉토리에 freemind .mm 파일을 올려서 일정을 관리를 하고 있습니다. 모든 사람이 마인드맵을 사용하는 것이 아니므로, 다른 사람들은 텍스트 파일로 작업관리를 하기도 합니다. 개인적으로 마인드맵과 버전 관리가 원활히 되면 정말 유용할거라 생각하는데, 아직 이런 기능을 제공하는 프로그램은 없는거 같네요. 제가 원하는 건 시간 돌리면서 변화를 눈으로 볼수 있으면 정말 좋을거 같습니다. CVS에서 옛날거 확인할수 있지만 그 과정이 귀찮아서 확인안하게 되더군요. 혹시 이런 기능 제공하는 프로그램 아시면 알려주세요 TT.

GNU screen

Linux Reality에서 screen에 대한 Podcast를 듣고 screen에 대해서 모르던걸 알게됐네요. GNU screen은 하나의 물리적인 터미널 안에서 여러 터미널을 사용할수 있도록 해주는 프로그램입니다. 한 터미널에서 여러 작업을 할때 매우 유용합니다. 또한, 작업하던 세션을 종료하지 않고 빠져나온 다음에 다른 곳에서 세션을 이어서 작업할수 있기 때문에 회사와 집 등 여러곳에서 작업할때 같은 환경에서 그대로 작업을 할수 있습니다. Podcast 들으면서 새롭게 안 기능은 여러 터미널에서 같은 screen 세션에 동시에 접속해서 작업할수 있다는 내용인데, 직접 해보니 Pair Programming할 때 아주 유용할거 같습니다. 그래서 검색을 해보니 위키(한글)에도 이러한 내용이 소개되어 있네요.

약 5년전에 하이텔(?)에 올렸던 글이 있어서 약간 내용 보충해서 올립니다.

—–

원격에서 작업하다 보면 여러창을 보고 싶을때가 많지만, 따로 로그인 하기도 귀찮고, 여러창 왔다갔다 할때도 어느 터미널이 어느 기계인지 많아지면 관리가 안되죠 –; 이럴때 사용하면 편리한 것이 screen입니다.

screen은 한 터미널 화면에서 여러 쉘과 프로그램을 띄울수 있으며, 또한 세션 관리 기능도 지원해서 터미널을 종료해도 나중에 다시 그 세션으로 복귀할수 있기 때문에 정말 편리합니다. 저는 이제 로컬에서도 screen을 애용하고 있네요.

먼저 시작은

% screen

또는

% screen -S 세션명

으로 시작하고, screen 실행후 모든 명령은 Ctrl-a로 시작합니다:

Ctrl-a, c : (create) 새로운 쉘이 생기면서 그 쉘로 이동
Ctrl-a, a : 바로 전 창으로 이동
Ctrl-a, n : (next) 다음 창으로 이동
Ctrl-a, p : (previous) 이전 창으로 이동
Ctrl-a, 숫자 : 숫자에 해당하는 창으로 이동
Ctrl-a, d : (detach) screen 세션에서 빠져나옴
Ctrl-a, x : lock screen

Ctrl-a, [ : 화면에서 텍스트 선택하여 클립보드로 복사 (화면 스크롤 가능)
            이때 vi와 동일하게 커서 이동할수 있고, space로 영역을 선택
Ctrl-a, ] : 클릭보드 텍스트 붙이기

Ctrl-a, S : (split) 창을 나눔 (region)
Ctrl-a, Tab : 다른 region으로 이동
Ctrl-a, Q : 현재 region을 제외한 나머지 숨기기

Ctrl-a, : : 명령모드로 들어갑니다.

위 명령 정도를 알고있으면, 불편하지 않게 사용할수 있으며, detach 시 세션이 종료되는 것은 아니고

% screen -r 세션명

으로 그전 세션을 다시 불러들일수 있습니다. 여러 창을 쓴다는 장점도 있지만, 세션 관리가 되는것도 아주 큰 장점입니다.

세션이 여러개 있으면 screen -list 하면 세션명이 쭉 나오고 (-S로 지정하지 않았으면 자동으로 이름이 할당됩니다)

세션을 완전히 종료하기 위해서는 모든 창에서 빠져나오면(exit 등으로) screen을 빠져나옵니다. 한번에 종료할려면 Ctrl-a : quit 하면 전체 창이 종료됩니다. 하지만 창을 하나씩 확인하면서 종료하는게 안전하겠죠.

split으로 화면을 나누면, 나눠진 공간(region) 별로 다른 창으로 전환할 수 있습니다.

% screen -x 세션명

-x는 -r과 동일하지만 그 전에 연결된 터미널을 끊지않고 세션에 동시에 연결합니다. 같은 세션을 여러명이 공유할수 있고, 세션에서 같은 화면을 보고 있으면 작업하는 내용이 실시간으로 보입니다.

스크린 사용하면 원래 사용하는 터미널의 히스토리 버퍼가 정상적으로 동작하지 않는데, 이때 Ctrl-a, [ 또는 Ctrl-a, ESC 를 이용하면 지나간 텍스트를 볼수 있습니다. 버퍼 크기는 .screenrc에서 “defscrollback 라인수”로 정할수 있으며 디폴트 값은 약간 작은 100 라인 입니다.

다음은 제 .screenrc 파일입니다. hardstatus는 여기를 참고했습니다.

vbell off
defscrollback 500
hardstatus alwayslastline
hardstatus string ‘%{gk}[%{wk}%?%-Lw%?%{=b kR}(%{W}%n*%f %t%?(%u)%?%{=b kR})%{= kw}%?%+Lw%?%?%= %{g}][%{Y}%l%{g}]%{=b C}[%H]%{W}’

hardstatus를 설정해서 맨 아래줄에 화면 리스트와 load average, 호스트명 등을 표시해줍니다.

CLucene CJK 분석기 (win32)

전에 CLucene CJK 분석기 리눅스용 소스를 공개하고 윈도우용도 공개하기로 했었는데, 계속 작업 안하고 있다가 마침 요청이 들어와서 정리했습니다.

압축파일에는 clucene-core-0.9.16a가 포함되어 있지 않으며, 압축을 풀고 아래와 같은 폴더 구조로 만들어주시면 됩니다. clucene 소스는 직접 받으셔야 합니다.


CLuceneTest 폴더에 프로젝트(dsw) 파일이 포함되어 있으며, Release에 실행파일을 포함했습니다.

실행을 하면 아래와 같이 간단한 창이 뜨며, 위쪽 텍스트를 라인별로 인덱싱하며, 가운데 검색창에서 쿼리를 입력하고 검색하면 아래 검색 결과가 나타납니다. 검색 버튼을 누를때 위쪽 텍스트에 변경 사항이 있으면 인덱싱을 한후 검색이 됩니다.

윈도우즈에서 CLucene 예제를 만들면서 몇가지 문제점이 있었습니다.

Visual Studio에서 위저드 통해서 MFC 프로젝트 만들면 Preprocessor에서  _MBCS가 정의되어 있는데, 이게 있으면 CLucene이 잘 컴파일이 안됩니다. 두가지 해결방법을 찾긴 했는데 둘다 근본적인 해결책은 아닌거 같네요.

첫번째 방법은 프로젝트 전체에서 _MBCS 정의를 빼버리는 방법이고, 두번째 방법은 CLucene의 “StdHeader.h” 에서 #undef _MBCS 하는 방법입니다. 두번째 방법은 clucene 소스를 한줄 고쳐야하기 때문에 제가 올리는 샘플 프로젝트에서는 첫번째 방법을 사용했습니다.

컴파일 할때 주의 사항은 CLucene에 해당하는 C++ 소스는 “CLucene/StdHeader.h” 파일을 precompiled header로 사용하도록 해야합니다. UI 부분과 Lucene 부분을 분리하여서 UI 쪽에서 Lucene 함수에 직접 접근하지 않도록 했습니다.

컴파일중에 다음 경고가 뜨긴 하는데 실험해본결과 퍼포먼스에 큰 문제는 없었습니다. (제가 사용한 응용 프로그램 기준)

==================Hashing not available or is disabled! CLucene may run slower than optimal ==================

그리고 디버그로 컴파일할때 internal compiler 오류가 납니다.

Fatal error C1076: compiler limit : internal heap limit reached; use /Zm to specify a higher limit

아래처럼 프로젝트 C++ 옵션에서 맨 아래 수동으로 /Zm400 옵션을 추가해주면 문제가 해결됩니다.

소스입니다.

1302547880.zip

네이버 사전 OpenSearch 플러그인

원서 보면서 사전 찾을때마다 좀 불편했는데, Firefox의 검색을 통해서 빠르게 네이버 사전을 찾을수 있도록 플러그인을 만들었습니다. 만드는 방법은 XML 파일 하나 만들면 되더군요. OpenSearch라는 표준?이 있나본데 Firefox 2.0 이상과 IE 7 이상에서 지원된다고 합니다.

IE 7은 현재 사용중이 아니라 테스트 못해봤고, 검색을 치는 도중에 자동 완성도 지원하는데, 네이버가 표준을 따르지 않아서 안되는거 같네요. 다음 페이지에서 설치할수 있습니다.

http://file.mix1009.net/opensearch/

아이콘은 Firefox 2.0에 포함된 네이버 검색에서 그대로 복사했습니다.

만들때 아래 URL을 참고했습니다:

http://developer.mozilla.org/en/docs/Creating_OpenSearch_plugins_for_Firefox

FIrefox에서 Ctrl-k 누르면 검색을 바로 할수 있고, 여기서 Ctrl-Up, Ctrl-Down 누르면 설치된 검색사이트를 선택할수 있습니다.

Mind Recursion (2005)

      mix1009-mind recursion.mp3

오랜만에 음악 하나 올리게 되는군요. 항상 마무리가 제일 어렵네요. 아이디어가 떠오를때 잠깐 녹음했다가, 한참후에 마무리하려니 생각처럼 잘 안되네요. 마음에 안드는 부분을 다시 녹음하려고 했었는데, 결국 다 삭제하고 원본으로 믹싱해버렸습니다. 기타, 베이스 직접 녹음했고 나머지는 미디입니다.

2005년 9월 녹음
2007년 5월 믹싱

GNU autoconf, automake

오픈소스 프로그램들은 대부분 리눅스에서 아래처럼 컴파일할수 있습니다.

$ ./configure
$ make
$ sudo make install

configure 스크립트를 실행하여 시스템에 맞게 컴파일 되도록 Makefile을 생성해줍니다. 유닉스가 종류가 많고 다양하기 때문에 그 모두를 Makefile 하나로만 지원하기는 어렵습니다. autoconf와 automake를 이용하면, 자동으로 타켓 시스템을 분석해주고, Makefile을 자동으로 만들어줍니다. configure를 실행하면 Makefile과 config.h 파일이 생성되는데, config.h에 시스템에서 제공되는 기능에 대해서 매크로로 정의를 해줍니다. 소스 파일에서 config.h를 include하고 매크로에 따라 특정 기능이 지원 안되면 다른 방법으로 구현하여 프로그램의 이식성을 높일수 있습니다. autoconf와 automake를 쓰는것만으로 프로그램 자체의 이식성이 높아지지는 않습니다.

저는 주로 FreeBSD에서 ports를 사용하고, 개발도 Berkeley Parallel make를 이용하기 때문에 autoconf와 automake를 배울 필요를 못느꼈었습니다. 사실 cross platform이 중요하지 않고 소스의 구조가 복잡하지 않으면 make의 기본 기능으로도 큰 불편없이 개발할수 있습니다. 요즘 빌드 시간도 짧으니 dependency도 크게 신경안쓰고 항상 make clean;make 해도 개발 자체가 크게 느려지지는 않더군요. 제가 유닉스에서 개발하는 프로그램은 대부분 5000 라인 이하의 데몬 프로그램들입니다. 거의 C에 가까운 C++ 프로그램이죠.

요즘 AMD64 서버들에 리눅스를 깔고 서버 프로그램들을 리눅스와 프비에서 동시에 지원하기 위해서 작업을 하고 있습니다. 처음에는 Makefile.linux를 따로 만들었는데 Makefile을 따로 관리하기 보다는 autoconf와 automake를 이용하면 더 편할것 같아서, autoconf, automake를 적용해보고 있습니다.

configure 스크립트가 만들어지기 까지 여러가지 명령을 순서대로 실행해야 해서 처음에는 복잡하게 느껴지지만 조금 익숙해지면 어렵지 않습니다. 사용자가 직접 만들어줘야하는 파일은 Makefile.amconfigure.ac 두개입니다. 나머지는 부수적인 파일들로 autoconf, automake 동작에 큰 영향을 주지 않습니다. (AUTHORS, README, COPYING 등)

libevent를 이용한 echo server를 C++로 예제 프로젝트로 만들어봤습니다.

Makefile.am에서는 실행파일과 실행파일을 만들기 위한 소스를 지정해줍니다. 아주 간단합니다.

bin_PROGRAMS = echo_server
echo_server_SOURCES = echo_server.cpp

configure.ac는 조금 복잡합니다. 프로그램 이름, 버전, 이메일 등을 적어주고 사용하는 라이브러리에 대해서 기술하도록 되어있습니다. libevent에 관련한 내용(파란색)이 대부분인데 이 부분은 memcached 에 포함된 configure.ac 파일을 참고했습니다.

AC_INIT(echo_server_libevent, 1.0, mix1009@gmail.com)
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
AM_CONFIG_HEADER(config.h)

AC_PROG_CXX
AC_PROG_INSTALL

AC_ARG_WITH(libevent,
   AC_HELP_STRING([–with-libevent=DIRECTORY],[base directory for libevent]))
if test “$with_libevent” != “no”; then
   CFLAGS=”$CFLAGS -I$with_libevent/include”
   CXXFLAGS=”$CXXFLAGS -I$with_libevent/include”
   LDFLAGS=”$LDFLAGS -L$with_libevent/lib”
fi

LIBEVENT_URL=http://www.monkey.org/~provos/libevent/
AC_CHECK_LIB(event, event_set, ,
   [AC_MSG_ERROR(libevent is required.  You can get it from $LIBEVENT_URL)])

AC_CONFIG_FILES(Makefile)
AC_OUTPUT

이 외에도 부수적으로 준비해야하는 파일들이 몇개있습니다. NEWS, README, AUTHORS, ChangeLog는 필수적으로 있어야하는 파일들이고, 몇가지는 automake를 실행할때 –add-missing을 인자로 주면 자동으로 만들어줍니다.

제가 사용하는 FreeBSD 6.2 기준으로 설명드리겠습니다. autoconf, automake 여러버전이 설치될수 있는데, 제가 사용한 버전은 아래와 같습니다.

/home/mix1009> pkg_info | grep auto
autoconf-2.59_2     Automatically configure source code on many Un*x platforms
automake-1.9.6      GNU Standards-compliant Makefile generator (1.9)

아래와 같이 실행하면 configure가 생성됩니다.

/home/mix1009/work/echo_server_libevent> ls -l
total 8
-rw-r–r–  1 mix1009  wheel    66 May  8 13:39 Makefile.am
-rw-r–r–  1 mix1009  wheel   650 May  8 13:39 configure.ac
-rw-r–r–  1 mix1009  wheel  3027 May  8 13:39 echo_server.cpp
/home/mix1009/work/echo_server_libevent> aclocal19
/home/mix1009/work/echo_server_libevent> autoheader259
/home/mix1009/work/echo_server_libevent> autoconf259
/home/mix1009/work/echo_server_libevent> touch README AUTHORS NEWS ChangeLog
/home/mix1009/work/echo_server_libevent> automake19 –add-missing
configure.ac: installing `./install-sh’
configure.ac: installing `./missing’
Makefile.am: installing `./INSTALL’
Makefile.am: installing `./COPYING’
Makefile.am: installing `./depcomp’
/home/mix1009/work/echo_server_libevent> ls -l
total 210
-rw-r–r–  1 mix1009  wheel       0 May  8 13:40 AUTHORS
lrwxr-xr-x  1 mix1009  wheel      35 May  8 13:41 COPYING@ -> /usr/local/share/automake19/COPYING
-rw-r–r–  1 mix1009  wheel       0 May  8 13:40 ChangeLog
lrwxr-xr-x  1 mix1009  wheel      35 May  8 13:41 INSTALL@ -> /usr/local/share/automake19/INSTALL
-rw-r–r–  1 mix1009  wheel      66 May  8 13:39 Makefile.am
-rw-r–r–  1 mix1009  wheel   17475 May  8 13:41 Makefile.in
-rw-r–r–  1 mix1009  wheel       0 May  8 13:40 NEWS
-rw-r–r–  1 mix1009  wheel       0 May  8 13:40 README
-rw-r–r–  1 mix1009  wheel   31538 May  8 13:40 aclocal.m4
drwxr-xr-x  2 mix1009  wheel     512 May  8 13:41 autom4te.cache/
-rw-r–r–  1 mix1009  wheel     640 May  8 13:40 config.h.in
-rwxr-xr-x  1 mix1009  wheel  150289 May  8 13:40 configure*
-rw-r–r–  1 mix1009  wheel     650 May  8 13:39 configure.ac
lrwxr-xr-x  1 mix1009  wheel      35 May  8 13:41 depcomp@ -> /usr/local/share/automake19/depcomp
-rw-r–r–  1 mix1009  wheel    3027 May  8 13:39 echo_server.cpp
lrwxr-xr-x  1 mix1009  wheel      38 May  8 13:41 install-sh@ -> /usr/local/share/automake19/install-sh
lrwxr-xr-x  1 mix1009  wheel      35 May  8 13:41 missing@ -> /usr/local/share/automake19/missing

처음 없는 파일들을 만들기 위한 명령인 touch와 automake 실행할때 –add-missing은 파일이 만들어진 이후로는 인자를 주지 않아도 됩니다. 파일이 모두 만들어진 이후로는 아래와같은 명령만 쳐주면 됩니다.

/home/mix1009/work/echo_server_libevent> aclocal19
/home/mix1009/work/echo_server_libevent> autoheader259
/home/mix1009/work/echo_server_libevent> autoconf259
/home/mix1009/work/echo_server_libevent> automake19


그리고 –add-missing으로 파일을 생성할때 심볼릭 링크로 생성되는데 소스를 배포하거나 CVS에 commit하기 전에, 파일을 직접 복사하는게 좋습니다.

configure 스크립트가 생성되면, 아래와 같이 타켓 시스템에서 컴파일할수 있습니다. configure가 만들어지기 전까지는 하나의 서버에서 실행해서 결과 파일들(configure, Makefile.in, config.h.in 등)을 배포하면 되지만, 이후 부분부터는 타켓 플렛폼에서 실행해야 합니다. configure가 실행될때 타켓 시스템에 특정 기능이 구현되었는지를 검사하고 라이브러리 설치여부등을 검사합니다. 그 결과에 따라서 config.h 파일을 만들어줍니다.

아래처럼 타겟 시스템에서 컴파일하고 설치할수 있습니다.

/home/mix1009/work/echo_server_libevent> ./configure –with-libevent=/usr/local
checking for a BSD-compatible install… /usr/bin/install -c
checking whether build environment is sane… yes
(생략)
checking for event_set in -levent… yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
/home/mix1009/work/echo_server_libevent> make
(생략)
/home/mix1009/work/echo_server_libevent> sudo make install
(생략)

리눅스에서는 configure를 인자없이 실행해도 libevent를 정상적으로 찾는데, FreeBSD에서는 위와 같이 인자로 지정해주어야 찾습니다.

각 툴들을 간략히 설명하겠습니다. aclocal은 autoconf에서 미처 구현되지 못한 부분(?)을 처리하는 것으로 차후에는autoconf에 포함될거라고 합니다. autoheaders는 configure.ac로부터 config.h.in을 만듭니다. automake는 configure.ac와 Makefile.am 내용에 따라서 Makefile.in을 생성합니다.autoconf는 configure.ac에 따라서 configure를 생성합니다. configure는 config.h.in과Makefile.in을 기준으로 시스템 정보를 분석하여 Makefile과 config.h를 만들어줍니다.

각 프로그램의 입출력 파일들을 살펴보면 아래와 같습니다. http://sourceware.org/autobook/의 Appendix C를 참고했습니다.

configure.ac — aclocal —> aclocal.m4
configure.ac, (optional aclocal.m4) — autoheaders —> config.h.in
configure.ac, Makefile.am — automake —> Makefile.in
configure.ac, (optional aclocal.m4) — autoconf —> configure
Makefile.in, config.h.in — configure —> Makefile, config.h

처음에는 복잡하게 느껴지지만, 한번 사용해보면 Makefile.am에서 소스 파일만 추가하고, 사용하는 라이브러리가 추가될때 configure.ac에서 라이브러리 지정만 하면 되기 때문에 사용에 어려움이 없습니다. 도입후에 여러 플렛폼에서 컴파일하면서 발생하는 문제점들을 하나씩 해결해 나가면 프로그램의 이식성을 높일수 있습니다. 문제가 발생하는 함수등을 configure.ac에서 지정하고 config.h에 정의된 매크로에 따라서 소스에서 적절히 처리하면 이식성이 차차 높아지게 됩니다.

autoconf, automake 실행하기 전 소스입니다. libevent를 이용한 echo 서버 예제 입니다. 소스 자체의 완성도는 높지 않습니다. configure.ac, Makefile.am, echo_server.cpp, COPYING 네개의 파일이 포함되어있습니다.

1214426580.tgz

ocaml-event를 이용한 echo server

ocaml-event(libevent ocaml wrapper)를 이용하여 echo server를 OCaml 언어로 작성해 봤습니다. libevent C API에 익숙해서 ocaml 답지 않게 짜진거 같은 느낌도 들지만 워낙 프로그램이 간단하다보니 크게 틀려질 부분은 없어보이는군요. 다른건 문제가 없었는데 Makefile에서 ocamlopt로 native 컴파일할때 C 라이브러리가 링크가 안되서 약간 헤맸고, printf 후에 flush stdout을 하는 부분이 있는데, stdout이 Unix 네임스페이스에 있는 stdout으로 인식이 되어 컴파일이 안되더군요. 그래서 Pervasives.stdout으로 지정하니 컴파일 잘되네요.

아래는 echo_server_event.ml 소스입니다.

[CODE type=ocaml]
(*
* echo server using libevent
*
* Copyright (c) 2007 Chun-Koo Park
* All rights reserved.
*)

open Unix

let rec sock_write sock buf offset = function
  | 0 -> ()
  | len ->
     let nwritten = write sock buf offset len in
       sock_write sock buf (offset + nwritten) (len – nwritten)

let echo_callback event fd event_type =
  let buf = String.create 64 and nread = ref 1 in
   while !nread > 0 do
     nread := read fd buf 0 64;
     sock_write fd buf 0 !nread;
   done;
   if !nread > 0 then
     Libevent.add event None
   else
     Printf.printf “connection closed\n”;
     flush Pervasives.stdout

let accept_callback event fd event_type =
  let asock, addr = accept fd in
  let evnew = Libevent.create () in

  Libevent.set evnew asock [Libevent.READ] false (echo_callback evnew);
  Libevent.add evnew None;

  Libevent.add event None

let tcp_server_sock port =
  let ssock = socket PF_INET SOCK_STREAM 0
  and addr = inet_addr_any in
   bind ssock (ADDR_INET (addr, port));
   setsockopt ssock SO_REUSEADDR true;
   listen ssock 5;
   ssock

let _ =
  let listenport = 2007 in
  let acceptfd = tcp_server_sock listenport in
  let acceptev = Libevent.create () in

  Libevent.set acceptev acceptfd [Libevent.READ] false (accept_callback acceptev);
  Libevent.add acceptev None;

  Libevent.dispatch ()
[/HTML][/CODE]

ocaml-event를 이용한 echo 서버와 thread와 fork로 짠 echo 서버의 Makefile입니다. ocaml findlib를 이용했습니다. ocaml findlib에 대해서 얼마전에 올린글을 참고하세요.

[CODE type=makefile]
# Makefile
#
# Copyright (c) 2007 Chun-Koo Park
# All rights reserved.

OCAMLC=ocamlfind ocamlc
#OCAMLC=ocamlfind ocamlopt

EXEC=echo_server_fork echo_server_thread echo_server_event
all: $(EXEC)

echo_server_fork: echo_server_fork.ml
   $(OCAMLC) -o $@ -package unix -linkpkg $@.ml

echo_server_thread: echo_server_thread.ml
   $(OCAMLC) -o $@ -thread -package “threads unix” -linkpkg $@.ml

echo_server_event: echo_server_event.ml
   $(OCAMLC) -o $@ -package “libevent unix” -linkpkg $@.ml -ccopt -L/usr/local/lib -cclib -levent

clean:
   rm -f *.cmo *.cmi *.cmx *.o $(EXEC)

# vi:set noet:
[/HTML][/CODE]

thread 사용할때는 -thread 옵션을 주고, ocamlopt로 native 컴파일할 경우를 위해서 -cclib로 libevent C 라이브러리를 지정해주었습니다. -cclib event로 지정하면 라이브러리를 찾을거라 생각했는데 -cclib -levent 형태로 라이브러리 지정을 해야되더군요. ocamlc로 byte compile할때는 -cclib 를 지정하지 않아도 됩니다.

Ocaml로 작성한 세가지 echo server 소스입니다. ( libevent / fork / thread )

1402904692.tgz