?SCons - A Software Construction Tool
--
김도집 2005-11-02 09:50:50
1 ?SCons #
Python 스크립트를 이용하는 소프트웨어 빌드를 위한 도구이다. 이는 make를 완전 대체한다.
개인의 취향에 따라 다르겠지만 나 개인적인 사용 소감은 make 보다 더 사용이 편리한 듯 싶다.
1.1.1 간단한 C/C++ 실행파일 빌드 #
hello.c라는 파일명으로 다음 소스 코드를 작성한다.
int main(void)
{
printf("hello world\n");
return 0;
}
SConstruct라는 파일명으로 다음 내용을 작성한다.
이제 쉘에서
scons를 실행하면 다음과 같은 결과 메시지가 출력될 것이다.
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -c -o hello.o hello.c
gcc -o hello hello.o
scons: done building targets.
아주 간단하게
hello라는 실행파일을 빌드 하는데 성공했다.
1.1.2 간단한 오브젝트 빌드 #
SConstruct 파일 내용에 Program 대신 Object를 사용한다.
1.1.4 Verbose를 적게... #
scons -Q를 실행한다.
- SConstruct 는 Python 스크립트이다.
- scons는 순차적으로 실행되지 않는다.
1.2 여러 개의 소스 파일일 때 간단한 빌드 #
여러 개의 소스 파일이 있을 때는 어떻게 빌드할까?
common = ['common1.c', 'common2.c']
foo_files = ['foo.c'] + common
bar_files = ['bar1.c', 'bar2.c'] + common
Program('foo', foo_files)
Program('bar', bar-files)
위에서 common은
Split() 메쏘드 method를 이용해서도 표현할 수 있다.
common = Spilt('common1.c common2.c')
다음은 실행 결과이다.
$ scons -Q
gcc -c -o bar.o bar.c
gcc -c -o common1.o common1.c
gcc -c -o common2.o common2.c
gcc -o bar bar.o common1.o common2.o
gcc -c -o foo.o foo.c
gcc -o foo foo.o common1.o common2.o
1.2.1 *.c를 몽땅 컴파일하기 #
*.c와 같이 확장자를 통해 컴파일 하고자 한다면 다음과 같이 한다.
import glob
import os
import string
env = Environment()
def src_glob (s):
here = os.getcwd()
os.chdir (env.Dir ('.').srcnode ().abspath)
result = glob.glob (s)
os.chdir (here)
return result
Program("foobar", src_glob("*.c"))
헤더 파일의 경로를 지정해 주는 경우엔 다음과 같이 사용한다.
Program("foo", CPPPATH="include")
1.6 Construction Environments #
빌드 시 사용할 환경 값을 변경할 수 있다.
SConstruct 파일의 내용이다.
env = Environment(CC = 'gcc',
CCFLAGS = '-O2')
env.Program('hello.c')
다음은 실행 결과이다.
$ scons -Q
gcc -O2 -c -o hello.o hello.c
gcc -o hello hello.o
주의할 점은 make에서 사용하는 CFLAGS가 아니라 '''
CCFLAGS'''이다.
1.9.1 command line options #
다음은
scons [option] 과 같이 사용되는 것을 정리한다. 예를 들면 다음과 같다.
$ scons -Q --implicit-cache hello
option | 설명 |
-Q | less verbose |
-c | 빌드 과정 중에 파생된 것들을 지운다 |
--implicit-cache | 의존적성을 검색하여 캐싱한다. 이후엔 캐시에 있는 것을 사용한다 |
--implicit-deps-changed | 재 검색하여 캐시 내용을 갱신한다 |
--implicit-deps-unchanged | 변경된 내용이 있더라도 기존 캐시된 내용을 사용한다 |
메쏘드 | 설명 | 예 |
Program | 실행 파일을 빌드한다 | Program('foo', ['foo1.c', 'foo2.c']) |
Object | 오브젝트 파일을 빌드한다 | Object(['foo.c']) |
Split | 리스트를 만든다 | Split('main.c file1.c file2.c) |
Library | 라이브러리를 만든다 | Library('foo', ['f1,c', 'f2.c', 'f3.c']) |
?StaticLibrary | 정적 라이브러리를 만든다 | |
?SharedLibrary | 동적 라이브러리를 만든다 | |
File | 명시적으로 파일 노드를 만든다 | hello_c = File('hello.c') |
Dir | 명시적으로 디렉토리 노드를 만든다 | classes = Dir('classes') |
Entry | 파일 또는 디렉토리 노드, 둘 다 될 수 있다 | xyzzy = Entry('xyzzy') |
?SourceSignatures | '?MD5' 또는 'timestemp' 둘 하나 | ?SourceSignatures('timestamp') |
?TargetSignatures | 'build' 또는 'content' 둘 하나 | ?TargetSignatures('build') |
?SetOption | ?SCons의 옵션을 지정 | ?SetOption('implicit_cache', 1) |
Ignore | 의존성을 무시한다 | Ignore(hello, 'hello.h') |
Depends | 의존성을 명시한다 | Depends(hello, 'other_file') |
Environment | 환경 변수 값을 설정 또는 가져온다 | env = Environment() |
Options | |
Help | |
?SConscript | recursive하게 ?SConstruct를 실행한다 | |
Export | |
Import | |
Return | |
Builder | |
Scanner | |
Repository | |
변수 | 설명 | 예 |
LIBS | 빌드시 사용할 라이브러리를 지정한다 | LIBS=['foo'] |
LIBPATH | 라이브러리가 있는 경로 | LIBPATH=['/usr/lib', '/usr/local/lib'] |
CCFLAGS | C 소스 빌드시 사용할 flags | CCFLAGS='-O2' |
CPPPATH | 헤더 파일 경로 | CPPPATH=['include','/usr/include'] |