make 때는 어렵지 않았는데 cmake 는 좀 성가시네
아래 링크 한번 읽어보자.
http://www.mail-archive.com/cmake@cmake.org/msg25922.html
우리프로젝트에 아직 적용하지 않은상태.
후에 필요하면 위 방법 시도해보자.
헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤
2010년 6월 8일 화요일
2010년 3월 19일 금요일
cmake, visual studio 사용자를 위해서 솔루션 뽑아주는 배치파일
나야 nmake, jom 류를 쓰지만 다른이들은 스튜디오를 주로 쓰니 아래 배치파일을 만들어 mkbld.bat 등으로 이름지어서 소스트리에 포함했다. bootstrap.bat 등이 더 적당한 이름이겠지만..
bld 를 만들고 그안에 debug, release 를 각각 만들어서 솔루션을 만들어주는 구조.
솔루션만들거면 디버그 릴리즈 구분하지 않아도 되는데 그럴경우 install 명령이 릴리즈 타겟만 설치하려고 하는 문제가 있어서 (버그인가?) 이런 형태로 사용하게 됐다.
bld 디렉토리는 는 hg 등에서 ignore 해주는것 잊지말자.
[code]
@echo off
if exist bld (
goto err
)
mkdir bld
cd bld
mkdir debug
cd debug
cmake -D CMAKE_CONFIGURATION_TYPES:string=Debug ..\..
cd ..
mkdir release
cd release
cmake -D CMAKE_CONFIGURATION_TYPES:string=Release ..\..
cd ..\..
goto exit
:err
@echo bld directory exists
:exit
@echo on
[/code]
bld 를 만들고 그안에 debug, release 를 각각 만들어서 솔루션을 만들어주는 구조.
솔루션만들거면 디버그 릴리즈 구분하지 않아도 되는데 그럴경우 install 명령이 릴리즈 타겟만 설치하려고 하는 문제가 있어서 (버그인가?) 이런 형태로 사용하게 됐다.
bld 디렉토리는 는 hg 등에서 ignore 해주는것 잊지말자.
[code]
@echo off
if exist bld (
goto err
)
mkdir bld
cd bld
mkdir debug
cd debug
cmake -D CMAKE_CONFIGURATION_TYPES:string=Debug ..\..
cd ..
mkdir release
cd release
cmake -D CMAKE_CONFIGURATION_TYPES:string=Release ..\..
cd ..\..
goto exit
:err
@echo bld directory exists
:exit
@echo on
[/code]
2010년 3월 18일 목요일
jom, nmake 에 -j 기능(병렬 컴파일) 구현한놈 우왕ㅋ굳ㅋ
cmake 릴리즈노트를 읽다가 NMake Makefiles JOM 제네레이터가 추가된걸 보고 궁금해서 뒤져보니 우왕ㅋ굳ㅋ 이놈이 바로 nmake 에 -j 붙인놈이네.
http://labs.trolltech.com/blogs/2009/03/27/speeding-up-visual-c-qt-builds/
http://qt.gitorious.org/qt-labs/jom
다운로드
바로 테스트 해봤는데 시간 줄어드는거 측정까진 못해보고 코어 여러개 쓰는것만 확인했다.
바로 얼마전에 찾다가 못찾았는데 이제라도 찾았으니 다행.
그나저나 cmake 로 솔루션 만들어서 본격적으로 다른이들과 같이 써보니 문제가 좀 많네.
나야 nmake 나 jom 쓰면 쾌적하지만
헐..
솔루션쪽까지 만들어주는건 꽤나 성가시다.
http://labs.trolltech.com/blogs/2009/03/27/speeding-up-visual-c-qt-builds/
http://qt.gitorious.org/qt-labs/jom
다운로드
바로 테스트 해봤는데 시간 줄어드는거 측정까진 못해보고 코어 여러개 쓰는것만 확인했다.
바로 얼마전에 찾다가 못찾았는데 이제라도 찾았으니 다행.
그나저나 cmake 로 솔루션 만들어서 본격적으로 다른이들과 같이 써보니 문제가 좀 많네.
나야 nmake 나 jom 쓰면 쾌적하지만
헐..
솔루션쪽까지 만들어주는건 꽤나 성가시다.
2010년 3월 12일 금요일
cmake, 서브프로젝트간 의존성 추적이 좀 부족해보인다.
예를들어 최상위 CMakeLists.txt 는 아래 세개의 서브프로젝트를 가진다.
[code]
add_subdirectory(foo)
add_subdirectory(bar)
add_subdirectory(main)
[/code]
foo, bar 는 라이브러리를, main 은 실행파일을 만드는데 main 에는 bar 를 링크해야 하고 bar 에는 foo 를 링크해야 한다. 뭐 사실상 라이브러리간 링크가 아니고 main 에 foo, bar 모두 링크해야 하지만 main 쪽에서 봤을때는 bar 만 보이고 foo 는 bar 뒤에 딸려오는 놈이라고 볼수있다. 즉 의미상 foo -> bar, bar -> main 의 관계가 생긴다.
foo 의 CmakeLists.txt 는 간단.
[code]
project(foo)
add_library(foo foo.c)
[/code]
bar 를 빌드할때는 foo 가 필요하다.
[code]
project(bar)
add_library(bar bar.c)
include_directories(${foo_SOURCE_DIR})
link_directories(${foo_BINARY_DIR})
target_link_libraries(bar foo)
[/code]
main 을 빌드할때는 bar 만 명시해주면 foo 는 cmake 가 알아서 붙여준다.
[code]
project(main)
add_executable(main main.c)
include_directories(${bar_SOURCE_DIR})
link_directories(${bar_BINARY_DIR})
target_link_libraries(main bar) // bar 가 필요하면 bar 에 필요한 foo 도 딸려온다.
[/code]
우왕굿.
그럴듯 해보인다.
main 은 직접적인 의존성이 걸린 bar 만 신경쓰면 되고 foo 는 존재조차 알 필요 없다.
하지만 저런식의 구성이 될경우 bar 는 foo 의 헤더를 인클루드 해서 main 에 까지 노출하는 경우가 태반이다. 즉 main 쪽에서 foo 쪽의 헤더를 찾아야 하고 cmake 는 링크 의존성은 줄줄이 해결해 주지만 인클루드 의존성은 해결해주지 않는다..
결국 main 의 CMakeLists.txt 에서 bar 뒤에 숨은 foo 에 접근을 해야할 필요가 생긴다
[code]
project(main)
add_executable(main main.c)
include_directories(${foo_SOURCE_DIR}) # 갓댐!
include_directories(${bar_SOURCE_DIR})
link_directories(${bar_BINARY_DIR})
target_link_libraries(main bar)
[/code]
흠. 뭔가 맘에 안드는 모양새다. bjam 은 include 의존성도 잘 풀어줬던걸로 기억나는데.. 뭐 cmake 가 계속 조금씩 나아지고 있으니 언젠가 방법이 나오겠지. 아니면 link_libraries 가 버려지고 target_link_libraries 가 나온것처럼 다른 명령어가 이미 추가됐을지도.. 는 아직(2.8 버전) 아닌거 같다.
추가.
흠 위에서 link_directories 를 매번 해줬는데 안해줘도 된다. target_link_libraries 가 알아서 경로까지 가져온다. boost 던가가 msvc 에서는 link_directories 를 해줘야 돌아서 버릇삼아 적은건데.. 후에 수정하자.
[code]
add_subdirectory(foo)
add_subdirectory(bar)
add_subdirectory(main)
[/code]
foo, bar 는 라이브러리를, main 은 실행파일을 만드는데 main 에는 bar 를 링크해야 하고 bar 에는 foo 를 링크해야 한다. 뭐 사실상 라이브러리간 링크가 아니고 main 에 foo, bar 모두 링크해야 하지만 main 쪽에서 봤을때는 bar 만 보이고 foo 는 bar 뒤에 딸려오는 놈이라고 볼수있다. 즉 의미상 foo -> bar, bar -> main 의 관계가 생긴다.
foo 의 CmakeLists.txt 는 간단.
[code]
project(foo)
add_library(foo foo.c)
[/code]
bar 를 빌드할때는 foo 가 필요하다.
[code]
project(bar)
add_library(bar bar.c)
include_directories(${foo_SOURCE_DIR})
link_directories(${foo_BINARY_DIR})
target_link_libraries(bar foo)
[/code]
main 을 빌드할때는 bar 만 명시해주면 foo 는 cmake 가 알아서 붙여준다.
[code]
project(main)
add_executable(main main.c)
include_directories(${bar_SOURCE_DIR})
link_directories(${bar_BINARY_DIR})
target_link_libraries(main bar) // bar 가 필요하면 bar 에 필요한 foo 도 딸려온다.
[/code]
우왕굿.
그럴듯 해보인다.
main 은 직접적인 의존성이 걸린 bar 만 신경쓰면 되고 foo 는 존재조차 알 필요 없다.
하지만 저런식의 구성이 될경우 bar 는 foo 의 헤더를 인클루드 해서 main 에 까지 노출하는 경우가 태반이다. 즉 main 쪽에서 foo 쪽의 헤더를 찾아야 하고 cmake 는 링크 의존성은 줄줄이 해결해 주지만 인클루드 의존성은 해결해주지 않는다..
결국 main 의 CMakeLists.txt 에서 bar 뒤에 숨은 foo 에 접근을 해야할 필요가 생긴다
[code]
project(main)
add_executable(main main.c)
include_directories(${foo_SOURCE_DIR}) # 갓댐!
include_directories(${bar_SOURCE_DIR})
link_directories(${bar_BINARY_DIR})
target_link_libraries(main bar)
[/code]
흠. 뭔가 맘에 안드는 모양새다. bjam 은 include 의존성도 잘 풀어줬던걸로 기억나는데.. 뭐 cmake 가 계속 조금씩 나아지고 있으니 언젠가 방법이 나오겠지. 아니면 link_libraries 가 버려지고 target_link_libraries 가 나온것처럼 다른 명령어가 이미 추가됐을지도.. 는 아직(2.8 버전) 아닌거 같다.
추가.
흠 위에서 link_directories 를 매번 해줬는데 안해줘도 된다. target_link_libraries 가 알아서 경로까지 가져온다. boost 던가가 msvc 에서는 link_directories 를 해줘야 돌아서 버릇삼아 적은건데.. 후에 수정하자.
2010년 1월 18일 월요일
cmake, 실행하는데 여러 파일이 필요한놈한테 파일 모아주기
퇴원후 첫글이네 흠.
ogre 1.6 을 구경하고있는데 이게 빌드후 실행시 여려가지 dll 하고 리소스 들이 필요하더라.
리소스는 복사하긴 좀 덩치가 커서 코드내에서 $OGRE_HOME 을 기준으로 찾게했고 ( 보통 cfg 를 쓰도록 구성되어있는데 이건 내취향이 아니다. 적어도 샘플수준 코드라면 이런저런 파일을 들고다니는건 귀찮기만 할 뿐. 코드에 박는게 속편하다.) 그외 dll 들은 적당히 복사를 해서 쓰도록 했다.
어쨌건 정리해두면 먼저 exe, dll 들이 모이는 디렉토리를 만들고 cmake 가 만드는 출력을 이쪽으로 돌렸다. 아.. ogre 쪽 dll 도 복사하도록 추가했다.
위에서 아래두줄은 내가만든 매크로.. 소스는 요렇다.
흠, 참고로 ogre 샘플제작을 편하게 하려고 만든 매크로도 걍 적어둔다..
흠 추가로, 원래 configure_file 을 쓰지 않고 cmake -E 를 써보려고 했는데 그쪽은 좀 성가셔서 하다 말았다. configure_file 은 cmake 가 실행되는 시점에 복사를 하는거라 흠.. 정확히 내가 원하는 동작은 아닌데.. 뭐 별수없지.
아.. ogre 에 대해서도 좀 적어둔다.
흠 3D 는 전혀 모르지만 접근하는데 큰 무리는 없더라. 물론 3D 를 모르니 의미없는 접근이지만. 어쨌건 예제들이 간단한 프레임웍들을 끼고있어서 scratch 에서부터 시작하는게 좀 짜증났다. cfg 등을 남발하는 구조도 초기접근시 좀 더러웠고.
ogre 1.6 을 구경하고있는데 이게 빌드후 실행시 여려가지 dll 하고 리소스 들이 필요하더라.
리소스는 복사하긴 좀 덩치가 커서 코드내에서 $OGRE_HOME 을 기준으로 찾게했고 ( 보통 cfg 를 쓰도록 구성되어있는데 이건 내취향이 아니다. 적어도 샘플수준 코드라면 이런저런 파일을 들고다니는건 귀찮기만 할 뿐. 코드에 박는게 속편하다.) 그외 dll 들은 적당히 복사를 해서 쓰도록 했다.
어쨌건 정리해두면 먼저 exe, dll 들이 모이는 디렉토리를 만들고 cmake 가 만드는 출력을 이쪽으로 돌렸다. 아.. ogre 쪽 dll 도 복사하도록 추가했다.
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/out)
set_output_dir(${CMAKE_BINARY_DIR}/out)
copy_ogre_dlls(${CMAKE_BINARY_DIR}/out)
위에서 아래두줄은 내가만든 매크로.. 소스는 요렇다.
# 컴파일 결과를 한곳으로.
# cmake 로 dll 들을 서브프로젝트로 만들경우 exe 와 다른 디렉토리에 떨어져 불편하니 이걸 써먹자.
# 예)
# set_output_dir(${CMAKE_BINARY_DIR}/out)
macro(set_output_dir dir)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${dir} CACHE PATH "Single Directory for all Libraries")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dir} CACHE PATH "Single Directory for all Executables")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${dir} CACHE PATH "Single Directory for all static libraries")
endmacro(set_output_dir dir)
macro(filecopy src dst)
configure_file("${src}" "${dst}" COPYONLY)
endmacro(filecopy src dst)
macro(copy_ogre_dlls dir)
if(CMAKE_BUILD_TYPE MATCHES Debug)
filecopy("${OGRE_HOME}/bin/debug/OgreMain_d.dll" "${dir}")
filecopy("${OGRE_HOME}/bin/debug/RenderSystem_Direct3D9_d.dll" "${dir}")
filecopy("${OGRE_HOME}/bin/debug/Plugin_OctreeSceneManager_d.dll" "${dir}")
filecopy("${OGRE_HOME}/bin/debug/OIS_d.dll" "${dir}")
else()
filecopy("${OGRE_HOME}/bin/release/OgreMain.dll" "${dir}")
filecopy("${OGRE_HOME}/bin/release/RenderSystem_Direct3D9.dll" "${dir}")
filecopy("${OGRE_HOME}/bin/release/Plugin_OctreeSceneManager.dll" "${dir}")
filecopy("${OGRE_HOME}/bin/release/OIS.dll" "${dir}")
endif()
endmacro(copy_ogre_dlls dir)
흠, 참고로 ogre 샘플제작을 편하게 하려고 만든 매크로도 걍 적어둔다..
macro(link_ogre3d target)
if(CMAKE_BUILD_TYPE MATCHES Debug)
target_link_libraries("${target}" OgreMain_d OIS_d)
else()
target_link_libraries("${target}" OgreMain OIS)
endif()
endmacro(link_ogre3d target)
macro(link_ogre3d_all)
if(CMAKE_BUILD_TYPE MATCHES Debug)
link_libraries("${target}" OgreMain_d OIS_d)
else()
link_libraries("${target}" OgreMain OIS)
endif()
endmacro(link_ogre3d_all)
흠 추가로, 원래 configure_file 을 쓰지 않고 cmake -E 를 써보려고 했는데 그쪽은 좀 성가셔서 하다 말았다. configure_file 은 cmake 가 실행되는 시점에 복사를 하는거라 흠.. 정확히 내가 원하는 동작은 아닌데.. 뭐 별수없지.
아.. ogre 에 대해서도 좀 적어둔다.
흠 3D 는 전혀 모르지만 접근하는데 큰 무리는 없더라. 물론 3D 를 모르니 의미없는 접근이지만. 어쨌건 예제들이 간단한 프레임웍들을 끼고있어서 scratch 에서부터 시작하는게 좀 짜증났다. cfg 등을 남발하는 구조도 초기접근시 좀 더러웠고.
2009년 7월 27일 월요일
C++ 빌드툴 벤치마크
http://retropaganda.info/~bohan/work/sf/psycle/branches/bohan/wonderbuild/benchmarks/time.xml
오 이런 벤치도 있었네.
scons 는 여전히 느리군.
역시 cmake 가 문법이 병신같지만 달리 대안이 없네.
뭐 사실 속도가 좀 느려도 IDE 용 프로젝트 파일 만들어주는 기능때문에
남들하고 같이 일하려면 cmake 외엔 답이없다.
흠. waf 는 예전에 내가 빌드툴 검토할땐 없던 녀석인데 내기억이 맞으면 아마 scons 에서 갈라진 놈으로 알고있는데 음. 나중에 시간나면 boost build 최신버전이랑 같이 다시 검토좀 해봐야 겠구먼. boost build 에 파이썬 올린다던게 구현이 됐나 모르겠네.
오 이런 벤치도 있었네.
scons 는 여전히 느리군.
역시 cmake 가 문법이 병신같지만 달리 대안이 없네.
뭐 사실 속도가 좀 느려도 IDE 용 프로젝트 파일 만들어주는 기능때문에
남들하고 같이 일하려면 cmake 외엔 답이없다.
흠. waf 는 예전에 내가 빌드툴 검토할땐 없던 녀석인데 내기억이 맞으면 아마 scons 에서 갈라진 놈으로 알고있는데 음. 나중에 시간나면 boost build 최신버전이랑 같이 다시 검토좀 해봐야 겠구먼. boost build 에 파이썬 올린다던게 구현이 됐나 모르겠네.
2009년 6월 24일 수요일
tinyscheme 윈도에서 빌드하기위한 cmake 스크립트
이전에는 리눅스에서 놀아본거고
이번에는 tinyscheme 을 윈도에서 빌드하려고 하니 좀 성가시네. msvc 버전문제 인가?
그래서 간단하게 CMakeLists.txt 를 만들어봤다. 물론! 빌드되는것까지만 확인해본 것이니
좀더 둘러보고 써야겠지만. 어쨌거나 적어둔다.
이번에는 tinyscheme 을 윈도에서 빌드하려고 하니 좀 성가시네. msvc 버전문제 인가?
그래서 간단하게 CMakeLists.txt 를 만들어봤다. 물론! 빌드되는것까지만 확인해본 것이니
좀더 둘러보고 써야겠지만. 어쨌거나 적어둔다.
펼쳐두기..
# 플래폼설정. 이거 외에도 코드에서 snprintf 를 _snprintf 로 access 를
# _access 로 식의 약간의 변경이 필요. 아 짱나.
add_definitions(-DWIN32)
# 요 워닝은 일단 무시
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4996")
# 이건 feature 설정들
add_definitions(-DUSE_DL=0 -DUSE_MATH=0 -DUSE_ASCII_NAMES=0)
# DLL 뽑아내고
add_library(tinyscheme SHARED scheme.c)
# 스탠드얼론도 뽑아내고
add_executable(tinyscheme scheme.c)
2010/01/22 추가. msvc9 에서 빌드해본거. 이전에 적은거랑 별 차이는 없다.펼쳐두기..
scheme.c 에 다음 추가.
#ifdef _MSC_VER
# include <io.h>
# define access _access
# define snprintf _snprintf
#endif
CMakeLists.txt 에 아래 추가
project(tinyscheme)
add_executable(scheme scheme.c dynload.c)
add_library(scheme scheme.c dynload.c)
configure_file(init.scm ${tinyscheme_BINARY_DIR} COPY_ONLY)
워닝제거를 위해선 아래도 추가( 내가 원해 misc.cmake 에 들고다니는 코드에서 발췌 )
macro(suppress_msvc_warnings ns)
if(MSVC)
foreach(n ${ns})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd${n}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd${n}")
endforeach(n ${ns})
endif(MSVC)
endmacro(suppress_msvc_warnings ns)
suppress_msvc_warnings(4996)
2009년 3월 30일 월요일
ubuntu, cmake, boost
ubuntu 가 짱나는게 개발툴들이 버전업이 느리다는거.
결국 ppa 를 찾거나 직접 빌드해서 설치해야 하는데
둘다 기분좋은 일은 아니다.
어쨌건 boost 를 쓰게 되기까지의 과정들
음.. 위 매크로가 추가되면서 내가 자주 써먹는 misc.cmake 는 모양이 이렇게 됐네. 보통 최상위 CMakeLists.txt 에서 이걸 인클루드 하도록 하고 쓰는게 내 현재 개발취향
PS
아..
환경변수에서 BOOST_ROOT 잡는거 잊지 말자.
PS.
오랜만에 C++ 에 boost 까지 써먹으니 빌드속도 쩌는구먼.
아 답답해
결국 ppa 를 찾거나 직접 빌드해서 설치해야 하는데
둘다 기분좋은 일은 아니다.
어쨌건 boost 를 쓰게 되기까지의 과정들
- boost 는 1.38 가져다 직접 빌드. bjam 오랜만에 써보니 인자들이 기억이 안나서 당황. ubuntu 패키지 시스템과 충돌을 피하려고 ~/boost 를 prefix 로 해서 깔았는데 이게 모든 삽질의 시작이 되었다.
- intrepid 의 cmake 가 boost 1.38 을 지원하지 않는 버전.. 후럴... ~/boost 아래 깔린 boost 라이브러리를 못찾는 문제가 있더라. https://launchpad.net/~pgquiles/+archive/ppa 추가해서 설치. 근데 이친구는 굉장히 많은 패키지를 제공하네.
- CMakeLists.txt 에 아래 매크로를 추가해줬다. 간단히 테스팅용도로 쓰는거니 매번 타이핑하는건 번거롭지. 처음안 아예 링크까지 매크로안에 포함시켜벼렸는데 그건 좀 그래서 다시 뺐다.
- 음. 그런데 매크로 짜는게 쉽지 않았다. cmake 스크립트가 워낙 졸렬해서..
# 간단히 만들어본 boost 사용
# 최상위 CMakeLists.txt 에서
#
# use_boost(1.38 system date_time filesystem)
#
# 식으로 버전적은후 필요한 컴퍼넌트들을 줄줄이 적으면 된다.
# foo 라는 바이너리에 부스트 라이브러리들을 링크할때는
#
# target_link_libraries(foo ${Boost_LIBRARIES})
#
# 요리 적으면 된다. 정말 편히 쓰려면 아예 link_libraries 를 박아도
# 되고.
macro(use_boost ver)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREAD ON)
# 아오 짱나. cmake 문법은 정말 드럽군. &rest 같은놈이 없어서 ARGV 를
# 복사하고 앞대가리를 뽑아냈다. 달랑 이거 몇줄 때문에 시간 꽤나 날아갔네.
set(components ${ARGV})
list(REMOVE_AT components 0)
find_package(Boost ${ver} EXACT COMPONENTS ${components})
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
endif()
endmacro(use_boost)
음.. 위 매크로가 추가되면서 내가 자주 써먹는 misc.cmake 는 모양이 이렇게 됐네. 보통 최상위 CMakeLists.txt 에서 이걸 인클루드 하도록 하고 쓰는게 내 현재 개발취향
펼쳐두기..
# gtags
find_program(gtags NAMES gtags)
if(gtags)
add_custom_target(tags ALL ${gtags} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMENT "TAGGING")
endif(gtags)
# 자주 쓰일것 같아서 매크로로 만들어둔다.
macro(use_project xs)
foreach(x ${xs})
include_directories(${${x}_SOURCE_DIR})
link_directories(${${x}_BINARY_DIR})
endforeach(x ${xs})
endmacro(use_project xs)
# 멀티쓰레드사용
macro(use_threads)
include(FindThreads)
link_libraries(${CMAKE_THREAD_LIBS_INIT})
endmacro(use_threads)
# sloccount
find_program(sloccount NAMES sloccount)
if(sloccount)
add_custom_target(sloc ${sloccount} ${CMAKE_SOURCE_DIR})
endif(sloccount)
# 테스트
macro(use_test)
include(CTest)
enable_testing()
endmacro(use_test)
# msvc 워닝 제거
macro(suppress_msvc_warnings ns)
if(MSVC)
foreach(n ${ns})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd${n}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd${n}")
endforeach(n ${ns})
endif(MSVC)
endmacro(suppress_msvc_warnings ns)
# 간단히 만들어본 boost 사용
# 최상위 CMakeLists.txt 에서
#
# use_boost(1.38 system date_time filesystem)
#
# 식으로 버전적은후 필요한 컴퍼넌트들을 줄줄이 적으면 된다.
# foo 라는 바이너리에 부스트 라이브러리들을 링크할때는
#
# target_link_libraries(foo ${Boost_LIBRARIES})
#
# 요리 적으면 된다. 정말 편히 쓰려면 아예 link_libraries 를 박아도
# 되고.
macro(use_boost ver)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREAD ON)
# 아오 짱나. cmake 문법은 정말 드럽군. &rest 같은놈이 없어서 ARGV 를
# 복사하고 앞대가리를 뽑아냈다. 달랑 이거 몇줄 때문에 시간 꽤나 날아갔네.
set(components ${ARGV})
list(REMOVE_AT components 0)
find_package(Boost ${ver} EXACT COMPONENTS ${components})
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
endif()
endmacro(use_boost)
PS
아..
환경변수에서 BOOST_ROOT 잡는거 잊지 말자.
PS.
오랜만에 C++ 에 boost 까지 써먹으니 빌드속도 쩌는구먼.
아 답답해
2008년 12월 16일 화요일
cmake 에 sloc 타겟 추가
sloc 란
http://en.wikipedia.org/wiki/Source_lines_of_code
sloccount
http://www.dwheeler.com/sloccount/
cmake 에 타겟 추가
http://en.wikipedia.org/wiki/Source_lines_of_code
sloccount
http://www.dwheeler.com/sloccount/
cmake 에 타겟 추가
# sloc
find_program(sloccount NAMES sloccount)
if(sloccount)
add_custom_target(sloc ${sloccount} ${CMAKE_SOURCE_DIR})
endif(sloccount)
2008년 10월 21일 화요일
cmake 로 빌드후 떨어진 바이너리를 ftp/http 등으로 업로드 하는 방법
일단 간단히 ftp 로 파일 하나 올리는것만 적어두고 나중에 더 쓰게되면 업데이트해야지.
중요한것은 add_custom_target 으로 curl 을 실행했다는것. 뭐 curl 이 잘되어있으니 앵간한건 죄다 이걸로 처리가 가능하겠지.
curl 사용법은 http://www.cs.sunysb.edu/documentation/curl/index.html 를 참고.
중요한것은 add_custom_target 으로 curl 을 실행했다는것. 뭐 curl 이 잘되어있으니 앵간한건 죄다 이걸로 처리가 가능하겠지.
curl 사용법은 http://www.cs.sunysb.edu/documentation/curl/index.html 를 참고.
add_custom_target(upload물론 이건 최소한의 사용법이고 프로젝트에 추가하려면 주소나 계정은 변수로 뽑아내고 여러 타겟등을 올려야 할테니 macro 를 만들어 써야할거다. 의존성거는것도 잊지말고...
COMMAND curl -T 올릴파일이름 -u 계정:암호 ftp://localhost/tmp/
WORKING_DIRECTORY ${proto_BINARY_DIR}
COMMENT "ftp uploading main.loud")
2008년 10월 20일 월요일
cmake 에서 LDFLAGS 를 타겟별로가 아닌 전체값을 바꾸기
CMAKE_EXE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS
변수 참고.
전에도 한번 쓴적이 있는데 까먹고 있었네
지금 cmake 로 크로스컴파일 세팅중인데
cmake 가 제안하는 방법대론 죄다 오류가 나길래
그냥 환경변수쪽에서 CC=arm-elf-gcc 잡아주고
CMakeLists.txt 에서 아래 코드 추가해서 대강 돌리고 있다.
회식시간이군.
나중에 재작성.
...
...
증상에 대해서 좀더 자세히 적어둘려고 했는데 귀찮네
버그같은데 어차피 패치될테고.
혹시나 해서 대강 적어두자면
cmake 2.4 시절에는 크로스컴파일을 공식적으로 지원을 안해서 그냥 컴파일러를 나타내는 변수 CMAKE_C_COMPILER 등을 강제로 다른걸로 바꾸고 돌리면 문제가 없었는데 2.6 때 크로스컴파일을 지원한다고 하더니 위 값을 바꾸면 캐시가 어쩌구 하면서 값을 되돌리고 다시 설정을 돌리더라. 내가 코드상에 값을 다시 바꿔놨으니 이게 계속 반복되면서 무한루프를 타더군.. 위 링크 문서에 보면 강제로 컴파일러를 세팅하는 force 뭐시기도 있는데 이것도 마찬가지로 무한루프질을 하고.. 쉘상에서 CC 를 아예 바꾸고 cmake 를 돌릴때만 문제가 없었다. 이게 버그 맞겠지 아니면 내가 잘못 쓴건가.. 그리고 ccache 랑도 같이 쓰고 싶은데 이것도 좀 후지게 도는 문제가 있더라.
CMAKE_SHARED_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS
변수 참고.
전에도 한번 쓴적이 있는데 까먹고 있었네
지금 cmake 로 크로스컴파일 세팅중인데
cmake 가 제안하는 방법대론 죄다 오류가 나길래
그냥 환경변수쪽에서 CC=arm-elf-gcc 잡아주고
CMakeLists.txt 에서 아래 코드 추가해서 대강 돌리고 있다.
# 크로스컴파일 관련 기능들이 이상하게 돌길래 일단은 크로스컴파일을
# 할때마다 CC 환경변수를 잡아주는 식으로 개발중이다. CMAKE_C_COMPILER
# 를 확인해봐서 arm 이란 말이 보이면 -elf2flt 를 옵션에 추가하자.
if(CMAKE_C_COMPILER MATCHES "arm")
# 바이너리 만들때만 넣어주면 되겠지
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} -elf2flt)
# -rdynamic 옵션을 꺼버렸다. 끄기전에 message 로 찍어보니 이 옵션
# -하나길래 걍 "" 로 바꿔버렸지.
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
endif(CMAKE_C_COMPILER MATCHES "arm")
회식시간이군.
나중에 재작성.
...
...
증상에 대해서 좀더 자세히 적어둘려고 했는데 귀찮네
버그같은데 어차피 패치될테고.
혹시나 해서 대강 적어두자면
cmake 2.4 시절에는 크로스컴파일을 공식적으로 지원을 안해서 그냥 컴파일러를 나타내는 변수 CMAKE_C_COMPILER 등을 강제로 다른걸로 바꾸고 돌리면 문제가 없었는데 2.6 때 크로스컴파일을 지원한다고 하더니 위 값을 바꾸면 캐시가 어쩌구 하면서 값을 되돌리고 다시 설정을 돌리더라. 내가 코드상에 값을 다시 바꿔놨으니 이게 계속 반복되면서 무한루프를 타더군.. 위 링크 문서에 보면 강제로 컴파일러를 세팅하는 force 뭐시기도 있는데 이것도 마찬가지로 무한루프질을 하고.. 쉘상에서 CC 를 아예 바꾸고 cmake 를 돌릴때만 문제가 없었다. 이게 버그 맞겠지 아니면 내가 잘못 쓴건가.. 그리고 ccache 랑도 같이 쓰고 싶은데 이것도 좀 후지게 도는 문제가 있더라.
2008년 10월 8일 수요일
cmake 에서 한벌의 소스로 디파인만 달리해가면서 여러개의 바이너리를 뽑는 방법. COMPILE_DEFINITIONS 속성!
- 참고링크는 생략 이넘들 버전업이 빠르니.. 그냥 http://www.cmake.org 에서 문서 링크 찾아보자.
제목대로 한벌의 소스로 디파인만 바꿔가면서 바이너리를 뽑아보려고 했는데
add_definitions 가 타겟별로 cflags 를 맥여주는놈이 아니라 좀 난감했다.
적당히 검색해보니 COMPILE_DEFINITIONS 라는게 있네!! 전에는 못봤던거 같은데.. 버전올라가면서 생긴건가.. 어쨌건 이놈을 쓰면 타겟별로 디파인을 달리 주는게 가능해진다.
문서에서 저놈의 존재를 보고 막연히 set_target_properties 로 세팅하면 되겠구나 했더니 안되더라.. 구글링 해보니 set_property 를 쓰더만.. 아 씨바.. 존나 땜질식의 문법.. 나중에 이런기능이 필요하면 다시 삽질할게 뻔하니 적어둔다.
아 추가로 문서보는게 더 빠르지만.. COMPILE_DEFINITIONS_<CONFIG> 식으로 빌드타입(디버그냐 릴리즈냐..)에 따라 알아서 물게 뜨도록 할수도 있다.
cmake_minimum_required(VERSION 2.6)
# 지금 이 디렉토리내의 코드들은 는 project(brpc) 라고 선언된 다른
# 디렉토리의 라이브러리를 쓰고있다.
include_directories(${brpc_SOURCE_DIR})
link_directories(${brpc_BINARY_DIR})
# 컴파일할 소스들
# 내 원래는 그냥 add_executable 안에 줄줄이 나열하는걸 더 좋아하지만
# 소스 한벌을 여러번 써야 하니 변수에 일단 넣어둬야겠지.
set(srcs
main.c
dispatch.c
session.c
methodtable.c
bpacket.c
mac.c
handshake.c
brpc.c
ping.c
env.c
proc.c)
# 로그켠놈을 빌드해보자.
# 그냥 지금까지 쓰던 그대로지. 코드안에서 기본적으로
# ENABLE_LOG_MACROS 을 1 로 정의하는 코드가 있기 때문.
# 사실 명시적으로 여기에도 추가하는게 좋겠지.
add_executable(main ${srcs})
target_link_libraries(main tcp util benc)
# 로그끈놈을 빌드해보자.
# 달리 설명이 필요없지. 저 더러운 set_property 신택스를 보자. 글고
# COMPILE_DEFINITIONS 에 "/DFOO" 식으로 주면 에러난다. "FOO" 로 줘야만
# 한다. 처음에 이렇게 줬다가 오묘한 에러를 내주길래 시간만 버렸다.
add_executable(main.silence ${srcs})
set_property(TARGET main.silence APPEND PROPERTY COMPILE_DEFINITIONS "ENABLE_LOG_MACROS=0")
target_link_libraries(main.silence tcp util benc)
2008년 9월 26일 금요일
cmake 사용시 add_test 로 추가한 테스트 케이스에 대해서 valgrind(윈도라면 purify) 등으로 메모리 릭 검사를 하는 방법
- http://www.cmake.org/Wiki/CMake_Testing_With_CTest 참고. 윈도 환경이라면 퓨리파이를 지원하는듯헌데 퓨리파이는 상용이라서....
ctest 의 기능중에 valgrind 로 테스트해주는 기능이 들어있네.
간단히 테스트 해보고 적어둔다. 대시보드 기능은 아직 안땡기는데..
꼴을 보니 곧 써봐야할것 같다.
어쨌건.. CMakeLists.txt 예제(일부분만)..
# CTest 를 인클루드하는것 잊지말자
include(CTest)
enable_testing()
# MEMORYCHECK_COMMAND 로 valgrind path 지정.
# 그외 기억해둘만한 변수로는
# MEMORYCHECK_COMMAND_OPTIONS
# MEMORYCHECK_SUPPRESSIONS_FILE
# 정도가 있다.
# 그냥 valgrind 를 쓰는 경우라면 딱히 지정안해도 되더라.
set(MEMORYCHECK_COMMAND valgrind)
# enable_testing, add_test 콤보는 지금까지 계속 써오던것.
# 이렇게 추가된 테스트케이스들을 대상으로 멤체크를 하려면
# ctest -T memcheck 명령을 주면 된다.
add_test(test_simple_decoding test_simple_decoding)
add_test(test_simple_encoding test_simple_encoding)
뭐 별거 없다. 내 개발환경이야 보통 리눅스일테니 valgrind 세팅은 생략해도 되고.. 그럼 남는건 기존 내가 즐겨 쓰던 세팅에 include(CTest) 가 추가된다는것 하나뿐이다.
위 테스트에 대해서 메모리 체크를 시행할때는 커맨드라인에서 ctest -T memcheck 를 때려준다. 모든 케이스에 대해서 메모리 체크가 이루어지고 마지막에 leak 이 있었던 케이스가 몇개인지 알려준다.
예를들어 내가 두개의 테스트를 가지고 있는데 모두 릭이 있을경우 요런 결과가 나온다.

그리고 릭을 잡고 났더니 요런 결과가 나온다. 결과가 눈에 잘 안들어 오는군.

추가.
make 에 NightlyMemCheck 란 타겟이 생겼는데 이게 위와 동일한듯. CTest 를 include 해서 그런지 못보던 타겟이 많이 보이는군....
2008년 9월 17일 수요일
cmake 로 빌드할때 다른툴(예를들어 lex 등)이 생성해낸 소스로 타겟을 만드는 방법..을 보여주는 간단하고 별 의미없는 예제
GENERATED 속성과 add_custom_target 을 이런식으로 써먹을수
있다..라는 글이지 lex 를 이렇게 쓰라는건 아니다. 만약 lex 를 써야
한다면 cmake 의 lex 지원 툴들을 먼저 찾아보고 없다면 macro 등으로
적절히 포장후 사용하자.
# 쪼까 드럽네.
# 나중에도 한번에 못만들어낼게 뻔하니 적어둔다.
# 샘플삼아 만들어본거라 이게 정석적인 방법이 맞는지는 모르겠고..
# 실무에 쓸상황이 오면 검색좀 해보고 쓰자.
#
#
# foo.yy.c 를 이용해서 foo 라는 실행파일을 생성
add_executable(foo foo.yy.c)
#
# 그런데 foo.yy.c 는 실제 소스가 아니고 cmake 시스템이 생성해내는
# 놈이므로 cmake 시스템에 그런 속성을 알려줘야 한다.
#
# 이건 사족이지만 짱나는게 있는데.. cmake 구버전 문서들은 cmake
# command 에 대문자를 주로 쓰지만 요즘엔 소문자도 쓰길래 나도 소문자로
# 써봤는데 커맨드이름이야 소문자가 잘 먹지만 인자중에 나오는 OUTPUT
# 이니 PROPERTIES 니 하는 것들은 대문자로 써줘야 돌아가는듯 하다.
set_source_files_properties(foo.yy.c PROPERTIES GENERATED true)
#
# add_custom_command 로 foo.l 로부터 foo.yy.c 를 생성하도록 해줬다.
# 몇가지 드러운점은.. 난 주로 소스디렉토리와 빌드디렉토리를 달리 하는데
# 그럴경우 디렉토리를 맟춰주는 삽질을 좀 해줘야 한다는것.
#
# 아래 코드를 보자면 빌드시에는 ${CMAKE_CURRENT_BINARY_DIR} 에서 작업이
# 진행되니 foo.yy.c 는 그자리( 이걸 소스디렉토리에 남길 이유는 없지 )
# 에 두고 flex 에 넘길 원본인 foo.l 을 지칭할때는 매번
# ${CMAKE_CURRENT_SOURCE_DIR} 를 지정해줬다.
add_custom_command(
OUTPUT foo.yy.c
COMMAND flex -o foo.yy.c ${CMAKE_CURRENT_SOURCE_DIR}/foo.l
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/foo.l)
보기 좋지 않군. 주석 제거한놈도 적어둬야지.
add_executable(foo foo.yy.c)
set_source_files_properties(foo.yy.c PROPERTIES GENERATED true)
add_custom_command(
OUTPUT foo.yy.c
COMMAND flex -o foo.yy.c ${CMAKE_CURRENT_SOURCE_DIR}/foo.l
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/foo.l)
2008년 7월 7일 월요일
cmake 2.4-patch 7 하고 ccache 사용시 cmake 가 컴파일러를 파악하지 못하는 문제
release 빌드를 했는데 최적화 옵션이 빠진것을 보고 make edit-cache 에서 t 로 모든 옵션 켜고 읽어보니 cmake 가 세팅해줘야 할 옵션들이 죄다 빠져있었다. 좀 생각해보니 ccache 가 문제인것 같은데 역시나 CC="ccache gcc" CXX="ccache g++" 로 환경변수 잡았던거 빼고 돌려보니 cmake 가 정상적으로 플래그들 세팅해주더라.
혹시나 또다시 삽질하는 경우를 피하기위해 적어둔다.
좀더 뒤지면 해결책도 나올것 같은데 그건 나중에.
아래는 FLAGS 들이 비어있는 상태. cmake 가 CMAKE_COMPILER_ARGS1 이란놈으로 뭔가 할것 같은데.. 결과는 그렇지 못했다.

아래는 정상일때. 컴파일러가 제대로 인식이 됐고 cflags 들이 적절히 세팅되었다.

혹시나 또다시 삽질하는 경우를 피하기위해 적어둔다.
좀더 뒤지면 해결책도 나올것 같은데 그건 나중에.
아래는 FLAGS 들이 비어있는 상태. cmake 가 CMAKE_COMPILER_ARGS1 이란놈으로 뭔가 할것 같은데.. 결과는 그렇지 못했다.

아래는 정상일때. 컴파일러가 제대로 인식이 됐고 cflags 들이 적절히 세팅되었다.

cmake 로 pkg-config 사용하기 ( CFLAGS, LDFLAGS 설정하기 )
이전위키에 적은글
씨바 cmake 깝깝하네.
걍 CFLAGS, LDFLAGS 만 세팅하는게 뭐이리 중구난방인지
급히 여기 적어두고 나중에 몰아서 새위키에 정리하자.
씨바 cmake 깝깝하네.
걍 CFLAGS, LDFLAGS 만 세팅하는게 뭐이리 중구난방인지
급히 여기 적어두고 나중에 몰아서 새위키에 정리하자.
# cmake 에 딸려오는 UsePkgConfig 를 쓰기로 했다.
# EXECUTE_PROCESS 를 써볼려고 헀는데 영 지저분해지길래 이놈을 쓴다.
INCLUDE(UsePkgConfig)
# UsePkgConfig.cmake 에 나온 예제 그대로
PKGCONFIG(gstreamer-0.10 GSTREAMER_INCLUDEDIR GSTREAMER_LIBDIR GSTREAMER_LDFLAGS GSTREAMER_CFLAGS)
# 인클루드 디렉토리 추가
INCLUDE_DIRECTORIES(${GSTREAMER_INCLUDEDIR})
# 링크 디렉토리 추가
LINK_DIRECTORIES(${GSTREAMER_LIBDIR})
# cflags 추가. cflag 에 -d 나 /D 만 있는게 아닌데 이딴 이름을 쓰는건 좀
# 아니라고 보는데.. 이 방법 말고 cmake 가 세팅하는 모든 CFLAGS,
# CXXFLAGS 를 수정하는 수단을 못찾겠다.
ADD_DEFINITIONS(${GSTREAMER_CFLAGS})
# 바이너리 하나 추가.
ADD_EXECUTABLE(a a.c)
# 그 바이너리에 LDFLAGS 적용. 이것도 절라 쓰레기 같은데.. 그냥
# 글로벌하게 LDFLAGS 를 수정하고 싶은데 깔끔한 방법이
# 안보인다. CMAKE_MODULE_LINKER_FLAGS 를 바꾸면 된다는데 SET 으로 저걸
# 바꾸는게 그다지 깔끔해 보이진 않는다.
SET_TARGET_PROPERTIES(a PROPERTIES LINK_FLAGS ${GSTREAMER_LDFLAGS})
피드 구독하기:
글 (Atom)