페이지

2010년 12월 27일 월요일

find.exe conflicts on Windows emacs

emacs를 사용할때 내부적으로 unix 툴인 find.exe를 사용하는데 이것은 Windows에 기본으로 내장되어 있는 find.exe프로그램과 이름이 같다. 따라서 emacs에서 unix의 find.exe를 call하고 싶어도 할 방법이 없다.

이것에 대한 해결책은 다음과 같다. 간단한 솔루션이지만 정말 많은 시간을 소비했다. --;;

Copy grep.exe and find.exe to Emacs’ own bin directory

2010년 12월 21일 화요일

Quickbuild script examples

Quickbuild를 잘~ 사용하려면 built-in script(OGNL)를 많이 사용해야 한다. script reference가 있음에도 친절한 수준은 아니라서 reference만 보고 하기에는 시간 낭비가 만만치 않다. 그래서 내가 사용했던 script snippet을 공유하면 도움이 되지 않을까 하는 생각에서 정리해 본다.

to use Quickbuild effectively, you should know how to use built-in script(OGNL). Though there is complete script reference, it's not easy to use it at first time. so It would be helpful for Quickbuild newbie to share these script snippet.


based on Quickbuild V3.x
+ Getting workspace directory of 'root/dev' on specific node.
${system.getConfigurationManager().get("root/dev").getWorkspaceDir()}
or
${system.getConfiguration("root/dev").getWorkspaceDir()}

+ Getting revision of last successful build of 'root/dev'
${system.getConfiguration("root/dev").getLatestSuccessfulBuild().getRepository("repo").getRevision()}

If TXT variable is equal to node's attribute value of 'CAP_GCC' returns true. otherwise returns false. This can be used at 'node match condition'.
node.getAttribute("CAP_GCC").equals("${vars.get("TXT")}")

check if this node is Windows OS
grid.getNode(params.get("nodes")).getAttribute("WRAPPER_OS").equals("windows")

+ return true if all specified step is successful
steps.get("master>sync").isSuccessful()&&steps.get("master>sdk").isSuccessful()&&steps.get("master>publish").isSuccessful()
+ select a build agent which doesn't have any job. this can be used at 'node match condition'
node.isBuildAgent() && (node.getJobCount()==0)
+ previous step is successful and check specific variable
current.getPreviousSibling().isSuccessful()&&vars.get("isPrevent").value=="no" 
+ add -c option when clean option checked
${vars.getValue("clean")=="yes"?"-c":""}


2010년 12월 6일 월요일

link again with another link option in cmake build tree

cmake를 사용하다 보면 다른 link option으로 같은 바이너리를 여러벌 만들어야 할 경우가 생길 수 있다. 손쉽게는 debug 혹은 release와 같이 configuration을 나눠서 여러번 빌드해서 원하는 것을 이룰 수 있다. 하지만 rebuild 없이 현재까지 빌드된 object파일들을 가지고 할 수 있는 방법이 있다면 더 효율적일 것이다.

그래서 고민한 끝에 얻은 결론은 link.txt를 이용하는 것이었다.  전체 적인 sequence는 :

  • "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${this_target}.dir/link.txt" 에 link command가 들어가 있다. 역시나 link할때 cmake -E로 이 파일을 이용해서 링크를 하고 있다.

  • 따라서 FILE(READ ...)로 link.txt을 read한 다음 내 입맛에 맞게 link option을 수정한다. STRING(REPLACE ...) 혹은 STRING계열 함수를 이용하면 쉽게 요리가 가능하다

  • 새로운 link command를 link2.txt로 저장한다.

  • 그 후 cmake -E로 해당 link command를 불러주면 된다.


나의 경우 한번은 --no_deubg 옵션이 들어가게 링크하고 또 다른 한번은 이 옵션 없이 link를 해야  할 필요가 있었다. 이것을 cmake macro로 단순화 하면 다음과 같다.

새삼 느끼는 거지만 cmake 참 좋다. ㅎ

[sourcecode]
MACRO(LINK_WITH_ANOTHER_OPTION _target)
FILE(READ "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_target}.dir/link.txt" _link)
STRING(REPLACE "--no_debug" "" _link2 ${_link})
FILE(WRITE "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_target}.dir/link2.txt" ${_link2})
# message(status ${_link})
# message(status ${_link2})
ADD_CUSTOM_COMMAND(TARGET ${_target}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E cmake_link_script "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${this_target}.dir/link2.txt" --verbose=$(VERBOSE)
COMMENT "link with different option ${_target}"
)
ENDMACRO(LINK_WITH_ANOTHER_OPTION)
[/sourcecode]

2010년 12월 3일 금요일

SidebySide(WinSxS) problem

Windows 계열에서 Dll hell문제를 해결하기 위한 하나의 방법으로 고안한것이 Side-by-Side tech 이다. dll 생성시 manifest파일을 만들고 그곳에 사용하는 버전의 crt버전을 적고 런타임시에 그 crt를 사용하는 기술이다.

최근에 겪었던 문제가 좀 복잡한 케이스 인데 상황을 설명하면 이렇다. Win7환경에서 Egg.dll을 빌드하자 아래와 같은 manifest.xml이 생성되었다.

[sourcecode language="xml"]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50727.4053" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
[/sourcecode]

우선 위 manifest에서 이상한 것이 debugCRT가 2개라는 것이다.

  1. 8.0.50727.4053

  2. 8.0.50727.762


더구나 1번의 8.0.50727.4053버전은 내컴에 존재하지도 않는다. 내 컴에서 빌드를 했음에도 4053이 있다!  그래서 실행하면 side by side error를 낸다.

이것은 무엇을 의미하느냐 Egg.dll이 link하는 3rt party lib중의 하나가 분명 4053버전으로 컴파일이 되었단 이야기다.  그래서 결과적으로 4053과 762버전 둘다 manifest에 들어가게 된것이고. 빌드는 이렇게 되었으나 runtime시에 해당 dll을 찾을 수 없다고 에러가 뜬다. 더구나 4053버전은 Win7을 support하지 않는다.

여기까지 왜 이런 문제가 생겼는지 까지는 이해가 되었다. 그럼 해결하는 방법은 msdn forum에 언급되었다. 발췌하면 아래와 같다.
The fact that both 762 and 4053 are listed in the same manifest is a big red flag.  This should never happen.  The only way it could possibly happen is that you are still linking to static libraries that have not been rebuilt to refer to 762 instead of 4053.  You should rebuild those static libraries.

If it's not possible to rebuild those static libraries i.e. they are third party libraries that you don't have access to, I suggest you follow instructions in the link below (a blog entry that I wrote over a year ago) to make your manifests show 762 only, not 4053.  Don't worry, this won't make your app less secure, if the appropriate 4053 DLLs have been installed on the user's machine, they'll still be loaded, through the power of policy redirection).  see:

http://tedwvc.wordpress.com/2009/08/10/avoiding-problems-with-vc2005-sp1-security-update-kb971090/

이와 별개로 manifest를 생성하지 않는것도 한 방법이다. 다소 risky 하긴 하지만..

2010년 11월 29일 월요일

Extracting VS2005 sln dependencies information

I have 220+ projects in my VS2005 solution file. My task is to create a new solution file by cutting some features. New one have 160+ projects and i need to set up dependencies between the projects.

To simplify these process i made Powershell script printing dependencies information. It worked as i expected. It will certainly ease your setting dependency work.

this script prints something like this:

projectA: projectB, base
projectB: base
...



Save the following script as Extract-VS2005Dependency.ps1
[sourcecode language="powershell"]
# usage
# powershell .Extract-VS2005Dependency -slnFile c:my.sln
param(
[string] $slnFile = $(throw 'need slnFile path')
)

$projects = @{}
switch -regex -file $slnFile
{
"^Project.*= ""(w+)"",.*vcproj"", ""(.*)""" {
#$_ ;
$projects[$Matches[2]] = $Matches[1]
}

}
#$projects
#$projects.count

switch -regex -file $slnFile
{
"^Project.*= ""(w+)"",.*vcproj"", ""(.*)""" {
#$_ ;
$curProject = $Matches[1]
""
write-host "$($curProject):" -nonewline
}
"({[A-Fa-f0-9-]+}) = 1" {
# $_
# $Matches[1]
write-host $projects[$Matches[1]]"," -nonewline
}

}
[/sourcecode]

2010년 11월 25일 목요일

converting vcproj to CMakeLists.txt

In official CMake wiki, there was several ruby script converters.
 
But the functionality I want is absent:
- Not supporting project configuration; converting 'debug|win32' configuration or 'release|win32' ?
- Not supporting exclude from build for each File configuration.
 
Since I have 150+ projects to convert , I write my own script using Powershell. It worked well for me. You don't need to install Powershell if you are using Windows7. it's already installed!
 
Note that this script supports only VS2005 project file only.
How to use:
  • Save powershell script in some directory(let's say c:tools)
  • Change your current directory to c:tools
  • Invoke following command.
  • CMakeLists.txt will be created in directory where vcproj located.

powershell .vcproj2cmake.ps1 c:xxx.vcproj -conf  'Debug'

2010년 11월 3일 수요일

mingw make patch for parallel build(-jN) on Windows

최근에 mingw make와 gcc 를 사용해서 프로젝을 빌드하는 프로젝트가 있다. 헌데 이놈이 맘에 안드는게 make -j를 지원하지 않는다. 그래서 4개나 되는 코아를 다 사용하지 못하니 빌드 시간이 오래 걸리고 컴이 놀게 된다.  -jN을 쓰지 못하면 너무 아깝지 않은가..
그래서 분석하기 시작!

I've been working on a project using mingw-make on Windows. but mingw-make doesn't support parallel build natively. Since my computers have 4 +cores, totally ineffective! so i'm digging about -jN options.

그래서 cmake로 Generator를 'MSYS Makefiles"로 바꿔서  parallel build(-j)에는 성공했지만, 버그때문인지 불규칙적으로 hang이 걸린다.  그래서 다른 방법을 찾아 보다가 찾은것이 Mingw job server를 제대로! 포팅한 패치가 있길래 mingw-make 3.82버전을 mingw환경에서 빌드해서 돌려보니 어라 잘 된다.

Using cmake's MSYS Generator was my first try. it did work. but there was some side effect. it irregularly caused deadlock.

I've found useful patch for supporting jobserver on Windows. i download mingw-make v3.82 and patch it. it gracefully works. no deadlock probelm.

또 유용한 patch를 발견했는데 이것은  parallel 하게 job이 수행되고 있는 중에 하나의 job이 실패하면 바로 리턴하는 patch. CI에선 거의 필수라 하겠다. 빠른 피드백이 중요하니까.
사실 윈도우에선 위 링크대로 하면 deadlock이 걸리길래 바로 'exit(4)'를 불러줬다.  그러니 child process들도 잘 죽는다.

i've found another useful patch which makes return at a first failure. default behavior is waiting for another job to be finished. the patch doesn't work on Windows. so instead i add 'exit(4)'. it killed all processes belonging to top process make.

혹시몰라 build & strip된 gnumake.exe를 첨부하려고 했으나
...  wordpress는 어떻게 첨부파일 어떻게 올리는건지 모르겠다..  zip같은건 원래 불가 ?

2010년 8월 25일 수요일

Unity Build

내가 요즘 하는 프로젝트는 상당히 규모가 있는 프로젝트이고, i5컴으로 빌드에만 3시간정도가 걸린다. 그래서 빌드 시간을 줄이는 것이 생산성에 중요한 key factor이다.

Our software platform is very large  and takes 3 hours to compile with i5 machine. so it is a crucial for productivity to reduce compile time.

그래서 어떻게 빌드 타임을 줄일 수 있을까 구글링을 하던 중에 재미난 것을 발견했다. 이름하여 Unity Build.

So i googled about it and found interesting article about Unity Build.

컨셉은 unity build를 위한 대표 cpp파일을 하나 만들고 그 파일에서 모든 소스 파일을 #include 하는 것.  즉 컴파일 해야하는 #cpp 파일을  줄이는 것이다.  이로서 매 cpp 마다 수행하던 preprocessing 을 줄고, 결과적으로 파일 IO가 줄어들게 되고, 이 때문에 빌드시간을 줄일 수 있다는 것.

The logic  is very simple. Unity build is all about making unity.cpp including all source files with '#include' macro.  Less #cpp means less file IO. that's the point.

장점:
  • 빌드시간 많이 2-3배 단축 가능
  • CMake를 사용한다면 function 하나로 바로 unity build로 바꿀 수 있다.

Pros:
  • overall build speed is 2-3 times faster
  • If you use cmake, applying Unity build is very ease. a function will automate all process.

단점:
  • incremental build에 취약..  cpp 파일이 하나만 바뀌어도 전체 필드를 해야 하니까.
  • 기존 소스를 그대로 사용할 수 없음. MM이 더 들어감.
    • 같은 로컬 변수를 사용할 때 심볼 충돌로 컴파일 에러.
    • include hierarchy가 꼬여서 빌드 에러
    • ...


Cons:
  • bad for incremental build. if a cpp file changes all cpp files in unity.cpp will be rebuilt.
  • usually you can't use as-is cpp. need more work!
    • compile error for same local variable in different cpp
    • compile error due to include hierarchy conflict
    • ...


우리 프로젝에 당장 적용할 수는 없지만, 흥미로운 시도임에는 틀림없다.  이 idea 기반으로 preprocessing과정 cache를 잘하면 빌드를 엄청 빨리 할 수 있다는 것이된다. next-gen 컴파일러는 아마 이런것을 지원 하겠지?

I can't use this in current project but this approach is very interesting and deserves mention. it means If we can cache  the preprcessing process, we can do much better ? will next gen compiler  implement this ?

2010년 5월 27일 목요일

Wiki adoption story

예전 글과 같은 논의/설득의 과정을 통해서 팀에 위키 도입하는 것에 성공했다. 하지만 내가 원한 상용 위키 도입은 미뤄졌다. 우선 무료 위키로 시작하고 본 궤도에 올라가면 상용을 써 보도록 하자고 결론이 났다.

우선 무료 위키 소프트웨어를 리스트 업해서 우리에게 맞는 위키를 하나 선택해야 했다. 후보는 DokuWiki, Media wiki, MoinMoin 등으로 압축되었다. 이중 WISWIG방식이 가장 쓸만한 MoinMoin으로 선택했다. 이유는 위키를 처음 접하는 사람들이 많았기 때문에 최대한 learning curve가 없어야 한다는 이유에서이다. 만약 그런 고려를 하지 않았다면 Media wiki를 사용했을것이다.

Moin을 설치하고 쓰기 시작! 예상대로 적극적으로 위키를 사용하는 사람들은 기존에 관심이 많았던 극소수에 불과했다. 이때부터 어떻게 사람들을 involve시킬 수 있을까 고민이 들기 시작했고 여러 문서들을 읽게 되었다. 외국에는 Wiki Evangelist라는 job title도 있었다.
 
크게 2가지 방식을 취한다. 첫번째로 유용한 컨텐츠를 추가해 나갔다. 여러가지 가이드 문서들 .doc으로 되어 있던 문서들을 위키로 옮겼다. 거의 나와 안선임님의 독무대. 허나 모든 내용을 우리 둘이서 작성할 수는 없는 일. 두번째로 유용한 use case를 발굴해 나가고 홍보했다.
- Release dashboard,
- Weekly report
- 각종 취합..
등으로..

처음엔 낯설어 하던 사람들이 점점 Wiki에 컨텐츠를 만들기 시작하면서 서서히 일상에 파고든다. 사람들이 일하는 패턴이 변하기 시작한다. I made it! 기존의 행동패턴을 바꾸는 것이 얼마나 힘든 일인가?
 
현재 위키는 위키는 우리 팀에 있어서는 안되는 툴로 인식되었다. 하여 매니지먼트는 상용위키 도입을 승인한다. 그리고 난 위키의 최고봉인 Atlassian의 Confluence 500 Users 라이센스를 구입하고 적용했다.. 역시 상용이라 WISWIG가 강력하다.
 
요즘에 고민하고 있는 것은 Wiki Content들의 정리다. 사람들은 제각기 생각이 다르고 글쓰는 스타일도 다르다.
- toc를 만드는 사람도 있고 안만드는 사람도 있고..
- Heading 2부터 시작하는 사람도 있고 Heading 이 아예 없는 사람도 있고..
해서 일관성과 체계성을 확보하기 위해서 또 많은 노력이 들어가야 한다는 것을 깨닫고 있는 요즘이다.

이제 Wiki Policy등을 만들어서 제각각인 패턴들을 하나로 수렴 해나가야 하는 숙제를 안고 있다.