2009-07-09 3 views
1

OS 클래스마다 구현이 다릅니다.
내 소스 구조는 다음과 같이이다 :멀티 플랫폼 C++ 프로젝트 : 플랫폼 별 소스 포함

  • 포함/AExample.h는
  • 은/창/WindowsExample.h
  • 포함/리눅스/LinuxExample.h
  • SRC/AExample.cpp
  • 포함
  • SRC/창/WindowsExample.cpp
  • SRC/리눅스/LinuxExample.cpp
,536,

A 클래스는 특정 구현을위한 인터페이스입니다.

현재 빌드 시스템은 cmake이지만 현재는 Linux 버전 만 빌드 할 수 있습니다. 윈도우에서

내 전류와 관련된 파일 만 포함 난 단지/* 파일을 리눅스에서 단지 리눅스/* 파일 내가
  • 필요

    을 창문을 포함 할 필요 구축 난 당신이 전문적인 방법으로 이것을 실현하기 위해 추천 할 수 있습니다 어떤 기술

AExample의 인스턴스를 필요로 할 때

  • 올바른 구현을 선택할 구축?

  • 답변

    7

    이것은 CMake에서 상당히 쉽습니다.

    CMakeLists.txt 파일에서 플랫폼을 확인하고 필요에 따라 적절한 파일을 추가하거나 적절한 하위 디렉토리를 포함 시키십시오.

    기본 구문은 다음과 같습니다

    IF(WIN32) 
        # Do windows specific includes 
    ELSEIF(UNIX) 
        # Do linux specific includes 
    ENDIF(WIN32) 
    
    2

    헤더가 같은 이름을 가지고 있지만 서로 다른 계층에있는 경우, 당신은 당신의 컴파일러 올바르게 -I (경로 포함) 플래그를 설정할 수 있습니다. 모든 플랫폼 종속적 인 포함을 개별적으로 처리하는 것보다 훨씬 쉽습니다. 헤더가 같은 디렉토리에 상주 및/또는 당신이 물건을 사용자 정의하려면

    , 당신이 당신의 C에서 이렇게 일반적으로 것입니다/C++ 코드 :

    #ifdef _WIN32 
        .. include Win headers .. 
    #endif 
    
    #ifdef LINUX 
        .. include Linux headers ... 
    #endif 
    

    내가 cmake 특정 솔루션 않는 권하고 싶지 않다 나중에 빌드 시스템을 전환 할 필요가 없다고 확신합니다.

    +1

    그러나 빌드에서 다른 소스 파일을 포함하여 처리하지 않습니다. 일반적으로 CMake를 사용하면 적절하게 설정되지만 플랫폼 별 소스 파일을 포함 할 수도 있습니다. 이것은 처음부터 cmake를 사용하는 이유 중 하나입니다. –

    +0

    이것은 작은 프로젝트에서는 쉽고 잘 작동하지만 프로젝트가 커질 때 문제가되는 기법 중 하나입니다. _ Large Scale C++ Software Design_은 근원 전체에 플랫폼 점검을 뿌리는 것을 권장합니다. 플랫폼 별 코드를 관리하기 위해 빌드 시스템을 사용하는 것이 가장 좋지만, 소스 자체에서 수행하려는 경우 더 많은 구조화 된 조직을 사용하는 것이 좋습니다 (http://stackoverflow.com/a/31304341/365496).). – bames53

    0

    크로스 플랫폼 파일을 처리하기 위해 빌드 시스템을 사용하는 것이 가장 좋지만 소스를 작성하여 전 처리기를 통해 처리하는 것이 가능하다고 생각합니다. 그러나 코드 전체에 플랫폼 검사를 뿌리는이 작업을 수행하는 매우 일반적이며 빠르며 더러운 방법은 문제가 있으므로 피해야합니다.

    대신 프로젝트가 커질수록 문제를 피하기 위해보다 구체적인 구조화 된 코드를 구성하는 방법을 사용해야합니다.

    플랫폼 특정 코드는 파일 수준에서 명확하게 식별해야합니다. 예를 들어 각 플랫폼에 대한 디렉터리가있는 디렉터리 구조를 사용하고 모든 플랫폼 별 소스 파일을 해당 디렉터리에 저장합니다. 소스 파일에는 여러 플랫폼 또는 전 처리기 플랫폼 검사에 대한 코드가 포함되어서는 안됩니다 (단 한 가지 예외). 또한 플랫폼 별 소스는 일반적으로 직접 작성되거나 #include이어야합니다. d. 대신, 플랫폼 특정 코드는 플랫폼 검사를 제외하고 플랫폼 특정 파일의 #include을 제외한 다른 플랫폼이 아닌 특정 소스 파일을 통해서만 간접적으로 사용해야합니다.

    예제 소스 조직 :

    src/ 
        main.cpp 
        foo.h 
        foo.cpp 
        windows/ 
        foo.cpp.inc 
        posix/ 
        foo.cpp.inc 
    

    예제 소스 내용 :

    // main.cpp 
    #include "foo.h" 
    
    int main() { 
        foo(); 
    } 
    
    // foo.h 
    void foo(); 
    
    // foo.cpp 
    #if defined(_WIN32) 
    # include "windows/foo.cpp.inc" 
    #elif __has_include(<unistd.h>) 
    # include<unistd.h> 
    # if defined(_POSIX_VERSION) 
    # include "posix/foo.cpp.inc" 
    # endif 
    #else 
    # error Unknown platform 
    #endif 
    
    // windows/foo.cpp.inc 
    #include "foo.h" 
    
    #include <iostream> 
    #include <Windows.h> 
    
    void foo() { 
        std::cout << "Windows\n"; 
    } 
    
    // posix/foo.cpp.inc 
    #include "foo.h" 
    
    #include <iostream> 
    #include <unistd.h> 
    
    void foo() { 
        std::cout << "POSIX\n"; 
    } 
    

    윈도우 빌드 및 출력 :

    cl.exe /EHsc /W4 /WX src\main.cpp src\foo.cpp
    main

    윈도우

    리눅스 빌드 및 출력 :

    g++ -Wall -Wextra -Werror -Isrc src/main.cpp src/foo.cpp
    ./a.out

    POSIX

    다른 플랫폼의 코드가 합리적으로 같은 파일 구성을 공유 할 수있는 경우 위의 예제에 표시된 방법이 매우 잘 작동합니다. 서로 다른 플랫폼의 코드가 서로 다르므로 각 플랫폼마다 서로 다른 파일 구조를 원한다면이 기술을 사용하는 것이 더 어렵습니다. 빌드 시스템을 사용하여 다른 플랫폼의 코드를 관리하는 것이 더 분명하게 우수합니다.

    또한 빌드 시스템을 사용하여이 기술을 혼합 할 수도 있습니다. 플랫폼간에 파일 구조를 공유하는 코드는 이것을 사용할 수있는 반면, 다른 플랫폼에 고유 한 모듈은 빌드 시스템에서 처리 할 수 ​​있습니다.

    관련 문제