플랫폼 간 호환성 (C ++)을 보장하는 기술은 무엇입니까?


13

(프레임 워크에 따라) 크로스 플랫폼이어야하는 가장 오래된 C ++ 프로젝트 중 하나를 마무리하고있었습니다. 라이브러리가 모두 크로스 플랫폼이기 때문에 OSX 빌드를 "나중에"수행하는 것이 쉽지 않을 것이라고 생각하면서 Windows와 Visual Studio에서 프로젝트를 완전히 개발했습니다. 이것은 사실이 아니라 "Windows 코드"가 제대로 실행되지 않아 컴파일 오류가 수정되었습니다.

코드가 모든 플랫폼과 호환되는지 확인하기 위해 어떤 기술이 존재합니까? 모든 플랫폼을 동시에 개발하여 서로 다른 플랫폼 버전을 하나씩 개발하지 않고 새로운 기능이 추가 될 때 동시에 모든 플랫폼에 대해 코드를 테스트합니까? (*)

특히 도구에 의존하지 않고 사용되는 도구에 관계없이 플랫폼 간 호환성을 돕는 "개발 프로세스"에 의존한다고 조언합니다. 위의 (*)처럼.


특히 WDL-OL ( https://github.com/olilarkin/wdl-ol ) 및 일부 크로스 플랫폼 DSP 라이브러리가 있는 VST 플러그인을 개발 중입니다. WDL-OL 프로젝트에는 VS 및 Xcode 프로젝트가 모두 설정되어 있지만 라이브러리에서 문제가 발생하고 컴파일러의 차이점이 있다고 생각합니다.


1
이식성 을 보장수있는 방법이없고 , 이식성을 향상 / 최대화하는 방법 만
phuclv

왜 이것이 중복되지 않습니까? 비슷한 질문이 많이 있다고 생각합니다
phuclv

귀하의 응용 프로그램은 무엇입니까? 어떻게 사용 하시겠습니까? 명령 행에서 또는 일부 그래픽 인터페이스를 통해? 하시기 바랍니다 귀하의 질문에 편집 을 향상시킬 수 있습니다.
Basile Starynkevitch 2016 년

그리고 어떤 프레임 워크를 사용하고 있습니까?
Basile Starynkevitch

답변:


15

이식 가능한 코드를 만드는 것은 매우 어려울 수 있습니다.

먼저 몇 가지 명백한 언어 관련 조언 :

  • 표준 C ++를 사용하고 정의되지 않은 동작을 신중하게 피하십시오
  • 주로 표준 라이브러리에 의존 (와 같은 휴대용 라이브러리 부스트 )
  • 항상 모든 예상 헤더를 포함하십시오. 헤더가 다른 헤더에 포함되어 있기 때문에 헤더가 필요하지 않다고 가정하지 마십시오 (예 : 하나의 특정 구현에 !) : 컴파일 오류가 발생할 수 있습니다
  • 컴파일러에서 지원하지만 C ++ 표준 (예 : 익명 구조체 또는 가변 길이 배열 ) 에서는 보장하지 않는 구문은 피하십시오 . 컴파일 오류가 발생할 수 있습니다.
  • 컴플라이언스를 강화하는 데 도움이되는 컴파일러 옵션 사용 (컴파일러 특정 확장 사용 안함, 리턴되는 경고 메시지 레벨 최대화)
  • 많은 구현에 의존 이동성의 함정이 있습니다 : 그것은 코드가 작동하는지 충분하지의 것을 명심 (심지어 초등학교) 데이터 형식의 크기, 수있는 문자 기본적으로 서명 또는 부호 , 대한 가정 엔디 언 , 표현의 평가의 순서 때이 부작용 등을 사용하십시오 .

그런 다음 몇 가지 설계 권장 사항이 있습니다.

  • 동등한 운영 체제 기능 대신 표준 라이브러리 대안 선호
  • 운영 체제 종속성 사용을 최대한 격리합니다 (예 : 조건부 컴파일로 제어되는 래퍼 함수에서)

마지막으로 섬세한 점 :

  • 문자 인코딩 : 많은 시스템에서 utf8에 의존 할 수 있습니다 . 그러나 Windows의 경우 시스템이 ansi 또는 utf-16을 기대함에 따라 더 섬세합니다. 물론 typedef에 의존 TCHAR할 수 있지만 (예 : 또는 ) 표준 라이브러리와 함께 사용하기 어려울 수 있습니다 (예 : cout또는를 wcout사용하는지에 따라 사용 ) charwchar_t
  • GUI / 그래픽 / 고급 I / O의 경우 기대 / 요구 사항에 맞는 휴대용 라이브러리를 찾을 수없는 경우 OS 별 구성 요소를 분리하기위한 전체 아키텍처를 설계하십시오. 래퍼는 여기에 관련된 많은 다른 상호 작용과 개념으로 인해 충분하지 않을 수 있습니다.
  • 예를 들어 추상 팩토리 (OS 관련 UI와 같은 관련 객체의 패밀리를 설계하는 데 이상적) 또는 중재자 (관련 객체의 패밀리 간 협업을 구현하는 데 이상적 ) 와 같은 흥미로운 디자인 패턴 을 활용하여 조건부 컴파일과 함께 사용하십시오. .

그러나 이것들은 조언 일뿐입니다. 이 영역에서는 확실성을 얻을 수 없습니다.


-Wall -Wextra -Werror
파이프

1
@pipe 또한 있어야합니다 -pedantic.
5gon12eder

@ 5gon12eder이 답변의 맥락에서 아주 좋은 지적입니다.
파이프

11

코드가 빌드, 실행 및 테스트 이외의 플랫폼과 호환되는지 보장 할 수있는 것은 없습니다. 따라서 모든 제정신이있는 사람들의 접근 방식은 모든 플랫폼에서 애플리케이션을 빌드, 실행 및 테스트하여 빌드, 실행 및 테스트해야하는 것입니다.

CI (Continuous Integration)는 일부 플랫폼 (대부분 Linux)에 대해 저렴한 또는 무료 빌드 에이전트를 얻거나 Windows에서 개발을 수행하고 문제가있을 때 간단히 Linux로 돌아갈 수 있기 때문에 소규모 프로젝트의 경우이 부담을 상당히 줄일 수 있습니다.

OSX CI는 꽤 까다 롭습니다.


CI 란 무엇입니까?
mavavilj 2016 년

5
지속적인 통합-기본적으로 빌드 및 테스트를 실행하는 많은 서버.
DeadMG

@DeadMG Mozilla Tinderbox와 같은 의미입니까?
Damian Yerrick 2018 년

1
Travis CI는 무료 OSX 빌드 호스트를 제공합니다
Daenyth

Cmake를 사용하십시오.
raaj

9

"개발 프로세스"를 요청하고 기본 개발 플랫폼이 Visual Studio가 설치된 Windows 인 경우 "windows.h"를 포함하지 않고 프로젝트를 빌드하는 것이 좋습니다. 코드를 리팩토링해야하는 많은 위치를 가리키는 많은 컴파일 오류가 발생합니다. 예를 들어, 'DWORD'는 #defined가 아니며이를 uint32_t모든 곳 으로 바꿔야합니다 (Google stdint.h은 정수 유형과 플랫폼 간 정의에 대한 유용한 정보를 제공합니다). 다음으로 Win32 API에 대한 모든 호출을 대체해야합니다.Sleep()크로스 플랫폼과 동등한 기능을 사용합니다 (Google은 가장 친한 친구이며 stack * .com 사이트에 관련 질문과 답변을 표시합니다). 당신은 아마 당신이 코드에 대한 모든 관련 크로스 플랫폼 교체를 찾을 성공하지 않으며 당신은 당신의 반환해야 include "windows."지침을하지만, 아래에 넣어 #ifdef _WIN32- 자세한 내용은 여기

보다 구체적인 질문을 계속하고 답변을 받으십시오. 이것은 "개발 과정이 무엇이어야하는지"에 대한 일반적인 제안입니다.

편집 1 또 다른 제안은 Windows 개발 시스템에서 Visual Studio와 함께 gcc 및 / 또는 clang을 사용하는 것입니다.


3

언급 한 "일부 컴파일 오류"에 따라 다릅니다. 그들이 무엇인지 알지 못하면 구체적 일 수는 없습니다.

Windows / Linux / iOS / Android / Mac 용 크로스 플랫폼 코드가 있습니다. 각각의 새로운 플랫폼은 처음 추가되었을 때 약간의 오류와 경고를 가져 왔습니다. 어떤 구성이 문제를 일으키는 지 빠르게 배울 수 있습니다. 그것들을 피하거나 #ifdefs 로 헤더의 차이점을 추상화하십시오 . #ifdef코드 자체 내에서 플랫폼간에 절대로 시도하지 마십시오 .

한 가지 예 :

void myfunction(MyClass &);
myfunction(MyClass());

반환 MyClass된 임시 인스턴스를 생성합니다 myfunction. 내 C ++ 컴파일러 중 일부에서 해당 인스턴스는 읽기 / 쓰기입니다 (그리고 일시적이며 곧 파괴 될 것이라는 사실은 컴파일러를 걱정하지 않습니다). 다른 사람들과 myfunction함께을 갖도록 재정의해야 const MyClass &하거나 컴파일러가 불평합니다. C ++ 표준이 무엇을 말하는지, 어떤 컴파일러가 옳고 어느 것이 잘못되었는지는 중요하지 않습니다. 오류가 두 번 발생하면 (a) 유형의 임시 변수를 선언 MyClass하고 전달 myfunction하거나 (b) 참조 const를 선언하고 여기저기서 불확실성을 myfunction사용하는 mutable것으로 알고 있습니다.

결론 : 경험을 축적하고 자체 코딩 표준을 개발하십시오.


2
그것은 MSVC의 잘못된 기능입니다. 당신의 요점은 1 시스템으로 개발하면 이것들이 들어올 수 있다고 지적합니다. 그러나 그 특정한 일은 당신이해야 할 일이 아닙니다.
JDługosz 2016 년

1
여러 툴 체인을 사용하는 한 가지 좋은 점은 공통 툴셋이 각각 개별적으로 허용하는 것보다 정확하고 표준을 준수하는 C ++ 일 가능성이 높다는 것입니다. 귀하의 경우, 표시된 코드는 표준에 의해 분명히 틀 렸으며 언급 된 수정 사항 모두 유효한 대안입니다. 나는 표준 말하는 것이 중요 하다고 말하고 싶다 .
5gon12eder

1
또는 크로스 플랫폼 C ++이 표준이 말하는 것보다 더 제한적이라고 말합니다. 다시 말해, 표준에 명시된 경우에도 지원해야하는 플랫폼에 대해 최저 공통 분모 (또는 최저 공급 업체 기능)가 적용됩니다. C ++ 11을 제외해야하는 오픈 소스 라이브러리가 많이 있습니다. 시민의 경우와 같이 일부 구성 요소는 C ++ 11을 지원하지 않기 때문입니다.
rwong

3

이식성을 돕는 가능한 방법 은 C ++ 11 표준이 제공하는 선언과 기능 에만 의존 하고 POCO & Qt 와 같은 크로스 플랫폼 라이브러리 및 프레임 워크를 사용하는 것 입니다.

그러나 이것조차도 완벽한 것은 아닙니다. 격언 기억

휴대용 프로그램과 같은 것은 없으며 특정 플랫폼으로 성공적으로 이식 된 프로그램 만 있습니다.

실습, 훈련 및 많은 경험을 통해 프로그램을 다른 플랫폼으로 이식하는 작업 은 일반적 으로 신속하게 수행 할 수 있습니다. 그러나 경험과 노하우가 중요합니다.


1
다른 조언은 다른 사람과 팀이 이식을 수행 할 때 코드 변경 사항을 메인 라인에 다시 통합해야한다는 것입니다. 그렇지 않으면, 플랫폼 차이는이를 수행 한 팀이 보유한 지식이됩니다.
rwong
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.