2009-06-23 3 views
20

나는 scons을 찾고 있는데, 나는 완전히 다른 것으로 뇌 세포의 덩어리를 투자하기 전에 대안이 무엇인지를 확실히 알고 싶다. 나는 과거에 GNU make를 사용 해왔지만 특히 그다지 만족스럽지 못했다.개미 + cpptasks 대 scons 대 확인

특히 : Ant가 C/C++ 프로젝트에서 더 자주 사용되지 않는 이유는 무엇입니까? (주어진 그곳에 ant cpptasks) 나는 개미가 자바 (분명히) 주위에 더 지향적이라고 말하는 몇 가지 게시물을 읽었지 만 그렇게하는 데에는 단점이 무엇인가? 그리고 왜 스콘이 만드는 것보다 훨씬 낫지?

저는 TI DSP 용 교차 컴파일러로 작업하고 있습니다. 일반적으로 프로젝트에는 20-50 cpp 파일이 있습니다. 빌드 관리에서 어려운 부분은 자동 종속 검사입니다. 다른 모든 것은 컴파일러 옵션 집합과 함께 파일 목록을 매핑하는 것입니다.

편집 : 왜 크로스 컴파일로 변경됩니까? 그것은 gcc가 실행하는 것과 같은 방식으로 실행되는 컴파일러입니다. 단지 내 PC에서 실행되지 않는 오브젝트 파일/실행 파일을 생성합니다.

답변

25

크로스 컴파일의 경우 최상의 선택은 CMake 또는 Autotools입니다. 특히 여러 아키텍처/플랫폼에 대한 코드를 컴파일 할 수있는 경우. 필자는 일반적으로 단위 테스트 목적으로 모든 코드를 기본 플랫폼에서 컴파일하고 대상 플랫폼에서 모든 코드를 컴파일합니다. CMake는 크로스 컴파일 된 라이브러리가 어디에 살고 있는지 지정할 수 있기 때문에이를 잘 처리합니다. 따라서/usr/lib에있는 크로스 컴파일 된 libpng를 검색하는 대신 빌드 머신에 도구 체인 라이브러리가 설치되어있는 곳이면/opt/arm-eabi-gcc /를 살펴야합니다. 서로 다른 변형에 대해 여러 개의 빌드 디렉토리를 만들고 make를 사용하여 각 변형을 수동으로 컴파일하거나 반복적 인 방법으로 반복적 인 make로 롤을 트리거 할 수 있습니다.

개미에는 바닐라 메이크처럼 기본적으로 좋거나 나쁘다는 단점이 있습니다. 단점은 C 또는 C++에서 특히 주류가 아닌 것을 사용하고 있다는 것입니다. 라이브러리 나 실행 파일의 헤더 파일과 같은 내부 파일과 타사 라이브러리와의 연결과 같은 외부 종속성과 같은 자체 의존성을 모두 처리해야합니다. 게다가 Ant C 태스크가 실제로 그렇게 많이 유지되지는 않는다고 생각합니다. 임무 작업으로 GCC를 호출하는 C 옹호자를 위해 Ant를 사용하는 사람은 누구나 보았습니다.

SCons가 더 좋지만 크로스 컴파일은 장점이 아닙니다. 그것은 CMake 또는 Autotools와 같은 "빌드 시스템"이 아니며 빌드 도구 일뿐입니다. 위키에서 말한대로 it is pretty much "Make in Python". 의존성에 대한 처리 기능이 내장되어 있습니다. 즉, "gcc -MM -MD"또는 그 자체로 롤백 할 필요가 없으므로 Make보다 이점입니다. SCons는 설치된 타사 라이브러리를 검색하는 기능도 지원하지만 대개의 방식으로 빌드 시간을 크게 늘릴 수 있습니다. 다른 시스템과 달리, SCons는 대부분의 결과가 캐싱되지만 검사 단계를 실행합니다. SCons는 긴 빌드 시간으로 인해 악명이 높지만 문제가되지 않는 파일은 50 개입니다. SCons의 교차 컴파일 지원은 존재하지 않습니다. - 자신을 굴려야합니다. as discussed on this thread on the mailing list. 일반적으로 빌드를 Unix 플랫폼처럼 강제 실행 한 다음 C 컴파일러의 이름을 무시합니다. 여러 변종을 만들거나 소스 디렉토리에서 빌드 디렉토리를 분리하면 코드가 얽혀서 코드를 교차하고 네이티브로 컴파일 할 때 적합하지 않게됩니다.

CMake 및 Autotools는 종속성 문제가 매우 잘 발생하고 autotools의 교차 컴파일 지원이 성숙합니다. CMake는 2008 년 4 월에 릴리스 된 버전 2.6.0부터 크로스 컴파일을 수행했습니다. 이러한 기능을 무료로 제공하고 패키징 및 유닛 테스트 ("확인 확인"또는 유사한 대상)를 실행하는 것과 같은 기능을 제공합니다. 이 두 도구의 단점은 부트 스트랩이 필요하다는 것입니다.CMake의 경우 Makefile 또는 Visual Studio 솔루션 파일을 만들려면 CMake 바이너리가 설치되어 있어야합니다. Autotools의 경우에는 소프트웨어를 컴파일하는 모든 사람이 automake와 autoconf가 설치되어 있어야하고, 빌드 시스템을 변경해야하는 사람 (빌드 시스템 변경시 새 파일을 추가해야 함) 만 필요하기 때문에 약간 더 복잡합니다. 2 단계 부트 스트래핑 (configure.ac -> configure, configure + Makefile.in -> Makefile)은 개념적으로 조금 까다 롭습니다.

편집 대상 : 크로스 컴파일은 프로그램 및 라이브러리의 자동 감지에 복잡성을 추가하기 때문에 빌드 시스템에서 추가 골칫거리입니다. SCons는이 문제를 다루지 않는다. 개미도 마찬가지입니다. autoconf는 autotools의 경우 이것을 처리하지만, 링크 단계에서/usr/lib를 사용하려고 할 때 연결이 끊어 지거나 직면 할 때 명령 행에 "--with-libfoobar =/some/path"를 제공해야 할 수도 있습니다 . CMake의 접근법은 툴체인 파일에 조금 더 많은 영향을 미치지 만, 이는 사용자가 알아 낸대로 툴과 라이브러리 (CC, CXX, RANLIB, --with-ibfoo = 등)를 모두 지정할 필요가 없다는 것을 의미합니다. 표준 협약. 이론적으로 CMake toolchain 파일을 여러 프로젝트에서 재사용하여 크로스 컴파일 할 수 있습니다. 실제로 CMake는 평범한 해커가 편리하게 사용할 수 있도록 충분히 넓지는 않지만 독점적 인 프로젝트를 여러 개 만들 경우 유용 할 수 있습니다.

1

개미는 자바 기반 사용자 기반이 매우 자연 스럽습니다. Ant가 훨씬 더 광범위한 환경에서 매우 유용 할 수 있다는 사실은 Java 개발자가 아닌 대부분의 개발자가 인식하지 못하는 것입니다. 결과적으로 Ant를 사용하여 C/C++을 빌드하는 경우 더 큰 사용자 기반 (CMake 또는 SCons)이있는 시스템을 사용하는 경우 자신 만의 코드를 작성하십시오.

개인적으로 저는 CMake가 정말 비주얼 스튜디오 프로젝트를 생성 할 수있는 유일한 빌드 시스템이기 때문에 매우 만족해했습니다. SCons도 가능하지만, SCons는 외부 호출 만하고, CMake는 Visual Studio의 자체 빌드 엔진을 사용하는 프로젝트를 생성합니다. 이는 Visual Studio에 익숙한 사람들과 함께 작업 할 때 매우 유용합니다.

CMake의 크로스 컴파일을 "성숙한"지원이라고 부를 수 있을지 확신하지 못합니다. 여전히 꽤 젊기 때문입니다. 그러나 CMake 사람들은 그것에 대해 심각하게 생각합니다. 그래서 나는 그것을 망설이는 것을 망설이지 않을 것입니다.

6

저는 JNI를 통해 새로운 Java 코드에 통합되는 매우 큰 코드베이스를 구축하기 위해 Ant + CppTasks를 사용했습니다. 매우 안정적인 점증적인 C++ 코드 빌드, 우수한 유연성 빌드 파일, 코드 수정 등). 하지만 CppTasks는 커뮤니티가없는 프로젝트이며 관리자 (Curt Arnold)는 오랫동안 아무 것도하지 않았습니다. 매우 유용하고 유용하지만, CppTasks를 알고 있거나 사용하는 사람이 거의 없다는 것을 알고 있어야합니다. (예를 들어, 컴파일러가 파일에 대해 "입찰"을하는 것은 내가 C 파일을위한 특정 컴파일러를 필요로 할 때 예를 들어 물었습니다. 대신).

CppTasks는 컴파일 옵션을 추적하고 헤더 종속성에 대해 소스를 동적으로 검색합니다 (종속성에 대한 일부 캐싱이 있음). 정확한 증분 빌드가있는 유일한 시스템이었습니다. 매우 큰 코드 기반을 구축 할 때 매우 중요한 사항입니다.

난 당신이 자바 물건을 많이 가지고 있고 이미 개미에 대한 투자가있는 경우 개미 사용자는/dev 목록에 몇 번, 이 문서에 다이빙을 두려워하지 않는 말한 그래서으로 CppTasks의 코드이며, 이제는 JNI "접착제"코드 및/또는 접착제 코드가 노출하는 "기존"기본 라이브러리를 구축해야합니다. 이는 가치있는 경쟁자이며 보상은 훌륭 할 수 있습니다.

예를 들어 .res 파일을 올바르게 포맷하는 작은 Ant 태스크 작성과 같이 완전한 버전 정보를 추가하기 위해 Windows DLL에 <rc>을 쉽게 통합했습니다.그것은 나를 위해 일했으나 Ant + CppTasks는 "고급"Ant 사용자/개발자 IMHO를위한 것입니다.

이 정보가 도움이되기를 바랍니다. --DD

3

ANT의 C++ 프로젝트를 빌드 할 때 terp을 추천합니다. 우리는 ANT가 우리가 선택한 빌드 도구이고 CppTasks가 약간 길어지고 다른 추상화 수준에서 작업하기를 원했기 때문에 우리는 터프를 개발했습니다. terp는 여러 컴파일러를 지원하며 회사에서 지원합니다. 대부분의 프로젝트에서는 무료가 아닙니다.

우리는 주로 의존성 분석이 포함 된 증분 빌드가 아닌 전체 재 구축을 위해 terp를 설계했습니다. 우리는 거기에 가고 있지만 그것은 아직 없습니다. terp의 가장 좋은 점은 모든 플랫폼에 대해 n 개의 다른 구성을 유지하고 싶지 않은 다중 플랫폼, 다중 프로세스, 다중 컴파일러 릴리스에 있습니다. 이 시점 (2009 년 7 월) 공개 베타 버전이지만 곧 출시 될 예정입니다.

2

나는 지난 5 년 동안 x86을하고 팔을 개미로 사용하여 프로젝트를 진행 해왔다. arm-gum-linux-gnueabi-와 같은 프리픽스 (prefix)를 전달하는 제네릭 컴파일러를 생성하기 위해 cpptasks를 수정했습니다. 그런 다음 g ++ 또는 ar 또는 기타와 같은 실제 도구 앞에 추가됩니다. 접두사가 없으면 개발 플랫폼 빌드 도구를 얻습니다. 크로스 컴파일을위한 툴체인은 빌드 툴 바이너리에이 접두사를 가지고 있습니다. Ant를 사용하는 것의 거의 모든 이유는 cpptasks의 inremental 빌드와 autoconf를 행복하게 유지해야만하는 일들의 발설이었습니다. 우리는 거의 모든 소스 파일, 특히 라이브러리 세트의 폴더 트리 구조에있는 소스 파일을 만들거나 이름을 바꾸거나 삭제할 수 있으며 빌드 파일을 편집 할 필요가 없다는 패러다임을 지원할 수 있습니다. 하나의 작은 단점은 불필요한 재 구축을 일으키는 방식으로 파일을 링크하는 속성을 업데이트한다는 것입니다.

<target name="lib.cvp"> 
<fetch.and.log.version 
    svnvers.target="common/cvp" 
    svnvers.property="libcvp.version"/> 
    <cc objdir="${obj.dir}/common/cvp" 
     commandPrefix="${command.prefix}" 
     compilerName="${compiler.name}" 
     outfile="${lib.dir}/cvp" outtype="static"> 
     <compiler extends="base.compiler"/> 
     <compilerarg 
      value="-D__CVP_LIB_BUILD_VERSION__=&quot;${libcvp.version}&quot;"/> 
     <compilerarg 
      value="-D__BUILD_NOTES__=&quot;${libcvp.toolversion}&quot;"/> 
     <compilerarg if="is.x86" value="-DARCH_X86"/> 
     <linker extends="base.linker"/> 
     <includepath refid="common.inc"/> 
     <fileset dir="${project.home}/common/cvp"> 
      <include name="*.c"/> 
      <include name="*.cpp"/> 
     </fileset> 
    </cc> 
</target>