현대 상용 어플리케이션들은 일반적으로 매우 복잡합니다. 아마 수많은 수의 소스 파일로 구성되어 있을 것이고 또한 수십만, 수백만 줄의 라인으로 구성되어 있을 것입니다. 소스 파일들은 보통 프로젝트 파일, 혹은 메이크 파일, 혹은 빌드 유틸리티에 따라 다른 빌드 파일에 의해서 조직되고 관리됩니다. 이러한 유틸티리 들의 대부분은 직렬 모드로 동작하고, 즉 이것은 빌드 타겟의 의존성에 따라서 하나씩 빌드 작업을 디스패치 함을 의미 합니다. 중견 규모 혹은 그보다 더 복잡한 어플리케이션들은 전체 어플리케이션을 재빌드 하는데에 수시간이 걸립니다. 빌드 프로세스를 빠르게 해줄 수 있는 유일한 방법은 빠른 머신 밖에 없는 것 같습니다. 여기서 질문은: 빠른 머신외에도 요즘의 네트워크 환경에서 이러한 프로세스를 빠르게 수행할 수 있는 방법이 있을까요? 답은 있다 입니다. 썬 스튜디오 솔루션이 그 해결책이 될 수 있습니다.
썬 스튜디오 소프트웨어는 통합 개발 환경입니다. 툴은 컴파일러 뿐만 아니라 디버깅 툴, 퍼포먼스 분석 및 최적화 도구 같은 여러가지 유용한 도구도 같이 제공하고 있습니다. 이러한 툴중에 하나가 바로 dmake 로 빌드 작업을 여러개의 CPU 혹은 여러개의 서버에 분산함으로써 병렬적으로 빌드를 수행하여 빌드 속도를 빠르게 해줄 수 있는 툴입니다. 이 글은 분산 빌드 환경 설정에 대해 설명하고 dmake 를 위한 makefile 수정의 가이드라인을 제공합니다.
dmake 는 Distributed Make 의 약자 입니다. 썬 스튜디오 소프트웨어에 딸려 오는 프로그램이고 표준 솔라리스 make 유틸리티를 보다 상위의 셋 입니다. 썬 스튜디오 소프트웨어는 솔라리스와 리눅스 버전을 둘다 가지고 있습니다. 그러므로 dmake 는 두 플랫폼에서 모두 사용 가능합니다. dmake 는 솔라리스 make 유틸리티가 가지고 있지 않는 특수한 기능을 제공합니다: 어플리케이션 빌드를 병렬로 수행하는 기능을 제공합니다. 썬 스튜디오 12 부터 4가지 모드가 제공됩니다:
- 직렬 모드(serial mode): 직렬 모드에서 dmake 는 표준 직렬 make 와 동일하게 동작합니다. 빌드 작업을 로컬 호스트에 디스패치 하여 하나씩 처리 합니다.
- 병렬 모드(Parallel mode): 이 모드에서 dmake 는 타겟을 병렬로 처리 합니다. 여전히 빌드 작업을 로컬 dmake 호스트에 디스패치 하지만 미리 지정한대로 복수개의 작업을 동시에 디스패치 합니다. 만약 로컬 머신이 여러개의 CPU 를 가지고 있다면 실제로 병렬로 작업을 수행할 것이고 그로 인하여 빌드 시간이 짧아 질 것입니다.
- 분산 모드(Distributed mode): 이 모드는 완벽하게 분산된 병렬 모드 입니다. dmake 는 빌드 작업을 미리 설정된 빌드 서버들에 미리 지정된 방법으로 분산하여 처리 합니다. 그리고 결과물은 dmake host 의 공용 폴더에 모아지게 됩니다 (즉, dmkae 의 공유 디렉토리가 서버를 제어 합니다).
- 그리드 모드(Grid mode): 이 모드는 썬 그리드 엔진과 같이 동작합니다. dmake 는 빌드 작업을 썬 그리드 엔진을 통해 분배합니다. 하지만 이 기능은 이 글의 범위를 벗어 납니다.
빌드 작업을 여러개의 CPU 혹은 여러개의 서버에 분산하여 디스패치 함으로써 dmake 는 빌드 절차를 병렬화 하고 시간을 단축할 수 있습니다. 이 기능이 다른 표준 빌드 유틸리티와 dmake 를 차별화 하는 기능입니다.
dmake 는 복수개의 CPU 혹은 복수개의 서버를 통해 어플리케이션 컴포넌트들을 동시에 빌드 함으로써 빌드 프로세스를 더 빠르게 진행 할 수 있습니다. 여분의 CPU 자원들과 서버들이 필요 합니다. 병렬 모드에서 올바르게 어플리케이션을 빌드하려면 어플리케이션의 어떠한 부분들이 동시에 빌드 될 수 있는 지를 지정하도록 약간의 makefile 수정 작업이 필요 합니다. 이러한 작업을 통해서 dmake 는 빌드 작업을 적절한 순서로 디스패치 할 수 있습니다. 분산 모드에서 소스 파일들과 결과 파일들은 dmake 호스트와 서버들간에 네트워크로 전송 됩니다. 네트워크에 부하가 걸리겠지만 아주 많이 걸리지는 않습니다. 그러므로 dmake 를 사용하기 전에 병렬 빌드 와 위에서 언급한 오버헤드 간에 장점을 잘 비교하여 고려해야 합니다.
dmake 사용을 결정할때에 고려해야할 몇가지 요소들을 정리하면 다음과 같습니다:
- 여러분이 복잡한 어플리케이션 즉 수많은 컴포넌트들과 많은양의 라인을 가지고 있고 직렬 빌드시에 반시간 이상이 걸린다면 dmake 를 사용하는 것은 좋은 생각입니다.
- 만약 오직 하나의 빌드 서버를 가지고 있다면, 그것이 복수개의 CPU 를 가지고 있고 여분의 CPU 자원을 가지고 있어야 합니다. 단일 프로세서 시스템이나 부하가 많은 시스템은 좋은 병렬 작업 프로세스를 보여주지 못할 것입니다.
- 만약 복수개의 서버를 가지고 있다면, 그들이 모두 동일한 아키텍쳐의 CPU 를 가지고 있는지를 확인하시기 바랍니다. SPARC 서버를 x86/x64 서버와 섞어서 하나의 종류의 바이너리를 빌드하기는 불가능합니다.
- 네트워크에 과부하가 걸려서는 안되고 네트워크 레이턴시에 심하게 영향을 주어서도 안됩니다. 만약 그렇지 않다면 분산 모드는 로컬의 직렬 모드 보다 훨씬 더 느릴 것입니다.
- 분산 빌드 모드는 리모트 쉘 (rsh) 과 NFS 가 필요 합니다. 만약 시스템들이 보안으로 보호된 네트워크 환경에 있지 않는다면 보안 우려 때문에 적절한 옵션이 아닐 수도 있습니다.
기본적으로 dmake 는 병렬 모드로 동작합니다. 즉 다시 말해서 병렬 모드를 활성화 시키기 위해 추가 적읍을 해주어야할 필요가 없습니다. 그러나 이전에 언급한대로 의존성에 맞게 적절한 순서로 빌드 작업을 디스패치 하기 위해서는 일단 몇몇 makefile 들을 고쳐야 합니다. 다음 섹션에서는 가이드라인에 대해 설명 합니다.
분산 모드를 활성화 하기 위해서 여러분은 빌드 환경을 먼저 설정해주어야 합니다. dmkae 를 분산 모드로 설정하기 위한 개념과 설정 예제는 다음과 같습니다:
- dmake 조종 서버는 dmake host 라고 부릅니다. 보통 소스 코드를 가지고 있습니다. 실제로 어플리케이션을 빌드 하는 서버를 빌드 서버라고 부릅니다. dmake 호스트는 빌드 서버가 될 수도 있습니다.
- dmake 호스트와 모든 빌드 서버가 동일한 버전의 운영체제와 동일한 수준의 패치 레벨을 가질것을 권장합니다. 그렇지 않으면 바이너리의 차이가 링크 문제를 유발할 수도 있습니다.
- dmake 호스트와 모든 빌드 서버들은 동일한 버전의 썬 스튜디오 소프트웨어를 사용해야 합니다.
- dmake 호스트는 NFS 를 통해서 소스 코드를 공유 합니다. 공유 디렉토리와 모든 서브디렉토리, 그리고 파일들은 아래에서 보시는 바와 같이 반드시 모든 빌드서버에서 읽기, 쓰기, 실행 권한 등이 가능해야 합니다.
root@dmake_host# share -F nfs \ > -o rw=<build servers delimited by colon> \ > /fullpath/to_source_root
- 모든 빌드 서버들은 아래에서와 같이 동일한 마운트 경로로 NFS 를 통해서 dmake 호스트의 동일한 물리적 디렉토리를 접근할 수 있어야 합니다.
root@build_server# mount -F nfs dmake_host:/fullpath/to_source_root \ > /fullpath/to_source_root
- dmake 호스트 이름과 모든 빌드 서버 이름들은 반드시 서로 간에 각각 해석이 가능해야 합니다. 그러므로 각각의 서버에서 서로간의 이름을 해석할 수 있도록
/etc/hosts와/etc/inet/ipnodes파일들이 반드시 올바르게 설정 되어야 합니다.
- dmake 호스트는 반드시 패스워드 입력 요구 없이 rsh 을 통해서 리모트 빌드 서버에서 명령을 내릴 수 있어야 합니다. 그러므로 모든 빌드 서버들과 dmake 호스트는 유저 로그인 이름과 유저 ID 측면에서 완벽하게 동일한 하나의 아이디를 가지고 있어야 합니다. 추가적으로 이 유저 로그인 계정을 가지고 있는 dmkae 호스트는 아래 처럼 반드시 다른 모든 서버에 의해서 신뢰 되어야 합니다.
appuser@build_server% id uid=201(appuser) gid=1 appuser@build_server% cat $HOME/.rhosts dmake_host appuser
appuser@dmake_host% id uid=201(appuser) gid=1
이전 코드에서appuser는 예제 유저 입니다. 이후에 표현되는 모든 유저 계정은 바로 이 계정을 말합니다. - dmake 유틸리티와 다른 썬 스튜디오 바이너리들이 설치된 bin 디렉토리는 반드시 모든 빌드 서버들의 접근이 그낭해야 합니다. 그리고 rsh 을 통해서 dmake 호스트에 의해 접근이 가능해야 합니다. 이렇게 하기 위해서 모든 빌드 서버의 유저 로그인 쉘은 C-쉘 (csh) 을 쓰도록 설정해야 합니다. 왜냐하면 rsh 커맨드를 실행할때 오직
$HOME/.cshrc지정된 환경 변수 만이 적용되기 때문입니다.appuser@build_server% echo $SHELL /bin/csh appuser@build_server% cat $HOME/.cshrc setenv PATH /opt/SUNWspro/bin:/usr/bin
appuser@dmake_host% rsh build_server which dmake /opt/SUNWspro/bin/dmake
/etc/opt/SPROdmake/dmake.conf파일에는 적어도 dmake 호스트로 부터 수락이 가능한 작업의 양이 의 되어 있어야 합니다. 이것은 빌드 서버에 존재해야 하고 빌드 서버의 유저 계정(appuser) 가 접근이 가능해야 합니다. 이 파일이 없이는 빌드 서버에서 dmake 작업 수행이 허용되지 않을 것입니다. 다음의 예제를 보시기 바랍니다.appuser@build_server% cat /etc/opt/SPROdmake/dmake.conf max_jobs: 2 nice_prio: 5
이전의 예제는 최대 작업 용량을 빌드 서버마다 2개로 설정했고 선택적으로 우선순위를 5로 지정했습니다.
- dmake 호스트는 분산 빌드 환경이 어떻게 최종적으로 설정될지를 정의 합니다. 기본적으로 dmake 는 dmake 런타임 설정 파일,
.dmakerc파일을 dmake 호스트 상에 빌드 유저의 홈디렉토리에서 찾습니다..dmakerc의 예제는 다음과 같습니다.appuser@dmake_host% cat $HOME/.dmakerc group "solaris10_x64" { host build_server_1 { jobs = 2, path="/opt/SUNWspro/bin" } host build_server_2 { jobs = 5, path="/export/home/SUNWspro/bin" } host build_server_3 { jobs = 8, path="/opt/SUNWspro/bin" } }
예제.dmakerc파일은 3개의 빌드 서버로 이루어진 빌드 서버 그룹 이름을solaris10_x64로 정의 했습니다.build_server_1은 최대 두개의 빌드 작업을 수락할 수 있고build_server_2와build_server_3는 좀 더 많은 작업-- 각각 5개 와 8개 의 작업을 수락할 수 있습니다. dmake 바이너리의 경로는 3개 서버마다 각각 다릅니다. 경로는 명시적으로 지정 되었습니다.
하나의.dmakerc 파일에는 복수개의 그룹이 존재할 수 있습니다.-g커맨드 라인 옵션 혹은DMAKE_GROUP환경 변수 혹은 매크로에 의해 명시적으로 그룹이 지정되지 않으면 첫번째 그룹 인스턴스가 사용 됩니다.
- dmkae 호스트의
.cshrc혹은.profile에는 두개의 환경변수가 추천되는데,DMAKE_MODE와DMAKE_ODIR이 바로 그것입니다.DMAKE_MODE는 기본 병렬 빌드 모드를 오버라이드 합니다.DMAKE_ODIR은 dmake 가 임시 파일을 쓰고 읽고 올 수 있는 공통 물리 디렉토리를 지정합니다. 기본적으로 디렉토리는$(HOME)/.dmake가 사용되고 반드시 모든 빌드 서버들이 이 장소를 볼 수 있어야 합니다. 만약 가능하다면.dmake의 부모 디렉토리를 동일한 소스 루트 디렉토리로 사용하시기 바랍니다. 왜냐하면 소스 루트 디렉토리는 어쨌든 반드시 NFS 를 통해서 네트워크로 공유 되어야 하기 때문이기도 하고 유저의 홈 디렉토리에 관계 없는 파일들의 노출을 막아주기도 하기 때문입니다. 그러므로DMAKE_ODIR은 dmake 호스트의 소스 루트 디렉토리 아래.dmake아래로 지정되어야 합니다. 또한 소스 파일과 새롭게 생성되는 파일들의 노출을 줄이기 위해서umask를0077로 설정합니다..cshrc파일의 예는 다음과 같습니다.appuser@dmake_host% cat $HOME/.cshrc setenv PATH /opt/SUNWspro/bin:/usr/bin:/usr/sbin:/usr/ucb:. setenv BASE_PATH /fullpath/to_source_root setenv MAKE dmake setenv DMAKE_MODE distributed setenv DMAKE_ODIR /fullpath/to_source_root/.dmake umask 0077
이렇게 지정함으로써 dmake 호스트에서dmake를 실행할때 매번 커맨드라인을 입력해야 할 필요가 없습니다. 그리고 모든 빌드 서버들에서 오직 appuser 만이 공유 디렉토리에 접근할 수 있습니다.
이제 분산 빌드 환경 설정이 완료 되었습니다.
dmake 를 병렬 모드 혹은 분산 모드로 실행하기 위해서는 일반적으로 makefile 을 약간 고쳐서 의존성에 따라 어떤 컴포넌트들은 병렬로 빌드되고 어떤것들은 안될지를 정의하는 작업이 필요합니다. 그렇지 않으면 dmake 는 의존성이 있는 컴포넌트들을 동시에 컴파일 하려고 할 수도 있고 의존하고 있는 컴포넌트 보다 먼저 컴파일 될수 있습니다. 이러한 경우 빌드는 실패할 것입니다.
Makefiles 은 어플리케이션마다 약간 다르게 조직될 수 있습니다. 모든 케이스에 대한 가이드라인을 드리는 것은 이 글의 범위를 벗어 나는 것입니다. 다음 섹션의 가이드라인은 계속해서 포개진 형태의 make (nested make 라고 불림) 즉 컴포넌트마다 하나의 makefile 이 있고 최상위 makefile 이 하위 컴포넌트들을 위한 make 를 순차적으로 호출하면서 빌드 순서를 조정하는 경우에만 잘 적용되는 가이드라인일 것입니다.
nested make 의 경우에 여러분은 먼저 최상위 레벨의 makefile 에 촛점을 맞춰야 할 것입니다.
- 각각의 make 를 호출 하는 부분은 서브타겟 레이블을 만들고 make 문자를 액션으로 집어 넣습니다.
- 이전에 생성된 모든 서브타겟 레이블들을 "all" 타겟 레이블의 암시적인 의존성으로 추가 합니다.
- 서브 타겟 간에 의존성이 존재하는지 분석합니다. 만약 그렇다면 관계된 서브타겟들의 의존성을 올바르게 설정합니다.
- dmake 빌트인 타겟
.PARALLEL을 모든 서브타겟 레이블에 삽입함으로써 전체적인 병렬 빌드를 활성화 시킵니다. 그리고 dmake 가 런타임 빌드 순서를 의존성에 맞게 판단하도록 합니다.
이러한 생각의 기본적인 예제를 표현한 것은 다음과 같습니다:
main.mak은 최종 실행파일을 빌드 합니다. 이것은 4가지 라이브러리에 의존하고 있는데libmylib1.so,libmylib2.so,libmylib3.so, 그리고libmylib4.so이 바로 그것입니다.libmylib1.so은libmylib2.so내의 함수들을 호출 합니다. 최상휘 makefile 이 모든 make 파일을 호출 합니다. 이것은 아래와 같이 변경 가능한데:appuser@dmake_host% cat Makefile include $(BASE_PATH)/Makefile.in all: $(MAKE) -f $(BASE_PATH)/src/mylib2/mylib2.mak $(MAKE) -f $(BASE_PATH)/src/mylib3/mylib3.mak $(MAKE) -f $(BASE_PATH)/src/mylib4/mylib4.mak $(MAKE) -f $(BASE_PATH)/src/mylib1/mylib1.mak $(MAKE) -f $(BASE_PATH)/src/main/main.mak clean: $(MAKE) -f $(BASE_PATH)/src/main/main.mak clean $(MAKE) -f $(BASE_PATH)/src/mylib1/mylib1.mak clean $(MAKE) -f $(BASE_PATH)/src/mylib2/mylib2.mak clean $(MAKE) -f $(BASE_PATH)/src/mylib3/mylib3.mak clean $(MAKE) -f $(BASE_PATH)/src/mylib4/mylib4.mak clean
위의 코드를 아래와 같이: appuser@dmake_host% cat Makefile include $(BASE_PATH)/Makefile.in TARGET= libmylib1.so \ libmylib2.so \ libmylib3.so \ libmylib4.so \ main .PARALLEL: $(TARGET) all: $(TARGET) main: libmylib1.so libmylib2.so libmylib3.so libmylib4.so $(MAKE) -f $(BASE_PATH)/src/main/main.mak libmylib1.so: libmylib2.so $(MAKE) -f $(BASE_PATH)/src/mylib1/mylib1.mak libmylib2.so: $(MAKE) -f $(BASE_PATH)/src/mylib2/mylib2.mak libmylib3.so: $(MAKE) -f $(BASE_PATH)/src/mylib3/mylib3.mak libmylib4.so: $(MAKE) -f $(BASE_PATH)/src/mylib4/mylib4.mak clean: $(MAKE) -f $(BASE_PATH)/src/main/main.mak clean $(MAKE) -f $(BASE_PATH)/src/mylib1/mylib1.mak clean $(MAKE) -f $(BASE_PATH)/src/mylib2/mylib2.mak clean $(MAKE) -f $(BASE_PATH)/src/mylib3/mylib3.mak clean $(MAKE) -f $(BASE_PATH)/src/mylib4/mylib4.mak clean
컴포넌트의 makefile 은 대부분 변경이 필요하지 않은데 왜냐하면 컴포넌트 makefile 은 오직 하나의 target 만을 가지고 있기 때문입니다. 만약 하나의 컴포넌트 makefile 에 여러가지 타겟들이 존재 한다면 이것은 최상위가 아닌 차상위 레벨의 makefile 로 다루시면 됩니다. 최상위 레벨의 makefile 수정과 동일한 가이드라인이 적용됩니다.
그러나 만약 컴포넌트 makefile 이 단 하나의 타겟만을 가지고 있더라도 만약 빌드 규칙이 다른 규칙에의해 생성되는 오브젝트의 소스 타입으로 제공될 중간자 타입의 오브젝트를 생성한다면 빌드 순서를 dmake 에 내장된 특별한 타겟인 .NO_PARALLEL, .PARALLEL, .LOCAL, 그리고 .WAIT 형태로 변경하는 작업이 필요 합니다. 즉 아이디어는 두번째 규칙 이전에 첫번째 규칙에서 모든 중간자 오브젝트들을 생성하는 것입니다.
예제는 다음과 같습니다:
- 솔라리스10 환경에서, 유저들은 그들 고유의 DTrace probe 를 C/C++ 소스 코드에 정의할 수 있습니다. 이 예제에서
main.c는main_dtrace.d에 묘사된대로 유저가 정의한 DTrace probe 를 포함하고 있습니다.My1func.c는my1func_dtrace.d. 에 묘사된 probe 를 포함하고 있고My2func.c는my2func_dtrace.d. 에 묘사된 probe 를 포함하고 있습니다. 최종 메인 실행파일을 빌드 하기 위해서 cc 를 이용하여main.c를 컴파일해서main.o를 얻습니다. 그 다음에 그다음에 dtrace 를 이용해서main_dtrace.o를 얻기 위해서 중간자인main.o를 이용해서main_dtrace.d를 컴파일 합니다. 유사하게 여러분은my1func.o와my1func_dtrace.o,my2func.o그리고my2func_dtrace.o를 얻으실 수 있습니다. 마지막으로main.o,main_dtrace.o,my1func.o,my1func_dtrace.o,my2func.o, 그리고my2func_dtrace.o를 이용해서 최종 메인 실행파일을 얻습니다. 원본 makefile 은 다음과 같습니다:appuser@dmake_host% cat main.mak include $(BASE_PATH)/Makefile.in DTRACE=dtrace TARGET=$(BIN_PATH)/main SRC_PATH=$(BASE_PATH)/src/main OBJECT= $(SRC_PATH)/main.o \ $(SRC_PATH)/main_dtrace.o \ $(SRC_PATH)/my1func.o \ $(SRC_PATH)/my1func_dtrace.o \ $(SRC_PATH)/my2func.o \ $(SRC_PATH)/my2func_dtrace.o all: $(TARGET) $(TARGET): $(OBJECT) $(CC) $(CFLAGS) -o $@ $? -ldtrace -L$(LIB_PATH) \ -lmylib1 -lmylib2 -lmylib3 -lmylib4 %_dtrace.o: %_dtrace.d $(DTRACE) -o $@ -G -s $< $(<:%_dtrace.d=%.o) .SUFFIXES: .c.o .c.o: $(CC) -o $@ -c $< clean: $(RM) $(TARGET) $(OBJECT)
표준 솔라리스 make 의 출력은 다음과 같습니다:
appuser@dmake_host% make -f main.mak cc -o /export/home/appuser/src/main/main.o -c /export/home/appuser/ src/main/main.c dtrace -o /export/home/appuser/src/main/main_dtrace.o -G -s /export /home/appuser/src/main/main_dtrace.d /export/home/appuser/src/main/ main.o cc -o /export/home/appuser/src/main/my1func.o -c /export/home/appus er/src/main/my1func.c dtrace -o /export/home/appuser/src/main/my1func_dtrace.o -G -s /exp ort/home/appuser/src/main/my1func_dtrace.d /export/home/appuser/src /main/my1func.o cc -o /export/home/appuser/src/main/my2func.o -c /export/home/appus er/src/main/my2func.c dtrace -o /export/home/appuser/src/main/my2func_dtrace.o -G -s /exp ort/home/appuser/src/main/my2func_dtrace.d /export/home/appuser/src /main/my2func.o cc -o /export/home/appuser/bin/main /export/home/appuser/src/main/m ain.o /export/home/appuser/src/main/main_dtrace.o /export/home/appu ser/src/main/my1func.o /export/home/appuser/src/main/my1func_dtrace .o /export/home/appuser/src/main/my2func.o /export/home/appuser/src /main/my2func_dtrace.o -ldtrace -L/export/home/appuser/lib -lmylib1 -lmylib2 -lmylib3 -lmylib4
그러나 만약 여러분이 dmake 를 makefile 을 수정하지 않고 곧바로 분산 모드로 실행한다면 cc 와 dtrace 는 동시에 실행될 것입니다. 중간자 오브젝트 파일들이 dtrace 가 시작해서 그것을 참고하기 전에 준비되지 않을 수 있습니다. 그러므로 dtrace 는 관련된
*_dtrace.o파일들의 빌드를 수행하지 못할 것입니다. 이 문제를 극복하기 위해서는 makefile 을 조정해서 cc 를 이용해서 중간자 오브젝트들을 dtrace 가*_dtrace.o를 생성할때 참조하기 전에 미리 빌드하고.WAIT를 사용하여 과정을 동기화 하는 것입니다.새로운 makefile 은 아래와 같습니다. 아래 섹션에서 굵은 부분이 문제를 해결한 부분입니다.
appuser@dmake_host% cat main.mak include $(BASE_PATH)/Makefile.in DTRACE=dtrace TARGET=$(BIN_PATH)/main SRC_PATH=$(BASE_PATH)/src/main OBJECT=$(SRC_PATH)/main.o \ $(SRC_PATH)/my1func.o \ $(SRC_PATH)/my2func.o \ .WAIT \ $(SRC_PATH)/main_dtrace.o \ $(SRC_PATH)/my1func_dtrace.o \ $(SRC_PATH)/my2func_dtrace.o all: $(TARGET) $(TARGET): $(OBJECT) $(CC) $(CFLAGS) -o $@ $? -ldtrace -L$(LIB_PATH) \ -lmylib1 -lmylib2 -lmylib3 -lmylib4 %_dtrace.o: %_dtrace.d $(DTRACE) -o $@ -G -s $<$(<:%_dtrace.d=%.o) .SUFFIXES: .c.o .c.o: $(CC) -o $@ -c $< clean: $(RM) $(TARGET) $(OBJECT)
추가정보
이 글의 영문 원본은
Accelerate Application Builds With Dmake
에서 보실 수 있습니다.
"개발자코너" 카테고리의 다른 글
- Solaris OS, SPARC Platform Edition에서 x86 Platfo... (댓글 1개 / 트랙백 0개) 2005/10/23
- DTrace 를 이용하여 썬 스튜디오 dbx 디버거 내의 감시점(watchpoint)... (댓글 0개 / 트랙백 0개) 2007/11/13
- dbx를 통한 Java 어플리케이션 디버깅: Java 코드를 위한 업계 최고 수준의 디버깅 (댓글 1개 / 트랙백 0개) 2005/11/23
- 솔라리스 상에서 "자바 GNOME" 바인딩을 이용해서 개발하기 (댓글 3개 / 트랙백 0개) 2007/04/20
- C++ 표준 라이브러리인 libCstd와 libstlport 비교하기 (댓글 1개 / 트랙백 0개) 2006/07/23
- 병렬 컴퓨팅을 위한 어플리케이션 개발 (댓글 1개 / 트랙백 2개) 2007/12/14
- 코어 덤프 관리 (댓글 3개 / 트랙백 0개) 2007/06/13
- OpenMP 소개: 공유 메모리 멀티 프로세서를 위한 포터블한 병렬 프로그램 API (댓글 5개 / 트랙백 0개) 2007/04/23
- 썬 스튜디오 익스프레스 IDE 퀵 스타트 가이드 (댓글 3개 / 트랙백 0개) 2007/05/18
- 솔라리스에서의 유저 인증 Part 4: PAM서비스 모듈 (댓글 0개 / 트랙백 0개) 2008/02/18
댓글을 달아 주세요