2012-08-10 2 views
2

큰 F # 프로젝트를 리팩터링했습니다. F # 컴파일러의 장시간 실행으로 모든 소스 파일을 컴파일하는 자동화 된 빌드 명령이 있습니다. 이것은 재현 가능한 빌드를 쉽게 할 수 있도록하기위한 것입니다. build 명령은 프로젝트를 빌드하기 전에 nunit-console을 실행합니다. 리팩토링 후, 내 단위 테스트의 큰 비율은 실패하기 시작 : NUnit를 사용하지 않고F # 2와 F # 3에서 발생하는 기괴한 F # 런타임 오류. NUnit이 실행 파일 실행을 거부 함

Exception: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

이 프로젝트는 F # 2.0 컴파일 할 때, 그리고 내가 명령 줄에서 같은 문제를 재현 할 수 있습니다 (즉,). stacktrace는 새로운 코드 (일부 데이터를 저장하는 생성자)가 삽입되어 있지 않은 점을 지적합니다.

그러나 F # 3.0을 사용하여 프로젝트를 컴파일하면 F # 2.0에서 문제가 발생하고 테스트를 통과 한 모든 단위 테스트가 실패합니다. 명령 줄에서 호출 할 때입니다 (NUnit을 사용하지 않음). NUnit은 이제 손으로 호출 할 수있는 새로 컴파일 된 실행 파일이 존재하지 않는다고 주장합니다. 상단에 파일을 찾을 수없는 예외가있는 긴 스택 추적이 있습니다. (필자는 F # 3.0을 사용하여 빌드 명령을 빌드하지 않았기 때문에 유닛 테스트가 여전히 괜찮습니다.)

Google은 HRESULT : 0x8007000B가 컴파일러 버그로 인해 발생했을 수 있음을 제안합니다. 불량 crasftsman 그의 도구를 비난의 경우지만, F # 3.0을 사용하면 문제가 사라집니다. 누군가 F # 2.0에서 다시 작동하도록하려고 제안 할 수 있습니까?

F # 3.0을 사용하는 데 너무 어려움이 없습니다. 하지만 실제로 NUnit이 필요합니다. 누가 잘못 될 수 있는지 아는 사람 있습니까? 다시 말하면, Nunit은 명령 행에서 시작될 때 정상적으로 실행되는 실행 파일을로드하지 못하고 F # 3.0을 사용하는 대신 F # 2.0을 사용하여 컴파일 할 때 같은 위치에서 동일한 실행 파일을로드합니다.

나는 이것에 대한 도움에 정말로 감사 할 것입니다. 많은 감사합니다.

답변

0

64 비트 프로세스에서 32 비트 어셈블리를로드하려고하면 (또는 그 반대로)이 오류 메시지가 나타납니다. Platform Target 프로젝트를 컴파일하는 대상은 무엇입니까 (프로젝트 속성 창의 빌드 탭에서 설정)?

내 생각에 프로젝트 설정이나 다른 구성 파일에 F # 2.0 컴파일러가 잘못된 플랫폼 대상으로 컴파일하는 원인이 될 수 있습니다. NUnit이 어셈블리를로드하려고 시도하면 NUnit 어셈블리 (32 비트 및 64 비트 시스템 용 특정 버전이 있다고 생각하는)와는 다른 '비트 니스 (bitness)'를 가지며 충돌이 발생합니다.

+0

전혀 지정하지 않은 것 같습니다. 그러나 단위 테스트의 약 80 %가 여전히 통과 되었기 때문에 이것이 아니라고 생각합니다. 그리고 그것이 무엇이든, 모든 것은 컴파일러의 한 실행에서 컴파일되기 때문에 충돌하는 플랫폼이 둘 이상 존재할 수 없습니다. 플러스 그것은 리팩토링 전에 잘 작동하고, 나는 buildsystem에 아무것도하지 않았다. 죄송합니다 모든이 일찍 언급하지 않았다. 그것은 일부 불일치가 있기 때문에 F # 3.0 버전은 Nunit에서로드되지 않을 수 있습니다. 시도해 볼만한 힌트는 무엇입니까? –

+0

이것은 사용하는 명령 줄입니다 : 'c :/Program Files (x86)/Microsoft F #/v4.0/Fsc.exe'-g --debug : full --tailcalls + --target : exe --warn : 4 --warnaserror : 76 --LCID : 1033 --utf8output - fulllpaths - flaterrors - out : "..."- doc : "..."--lib : "..."- 정의 :"DEBUG "- 정의 :"TRACE "- 참조 :"FSharp.PowerPack.Parallel.Seq.dll "- 참조 :"nunit.framework.dll "- 참조 :"FsCheck.dll " - 참조 : "System.Xml.dll"- 참조 : "System.Xml.Linq.dll"(많은 수의 .fs 파일 뒤에 있음) –

+0

모든 것이 도착하더라도 충돌하는 대상 플랫폼이 계속있을 수 있습니다. (즉, 하나의 어셈블리로 컴파일된다.) 컴파일 된 어셈블리와 NUnit 사이에서 충돌이 일어난다. 만약 당신이 64 비트 NUnit을 가지고 있고 32 비트 어셈블리를 테스트하려고한다면, NUnit이 리플렉션을 통해 어셈블리를로드하려고 할 때 BadImagePlatformException과 충돌합니다 –

0

이것은 바인딩 리디렉션 문제 일 것 같은 냄새가납니다. NUnit을 호출 할 때 DLL/EXE를 전달하거나 .nunit 파일을 전달합니까? 두 경우 모두 VS2012의 새로운 ConsoleApplication 프로젝트와 동일한 바인딩 리디렉션 (예 : FSharp.Core 2.0.0.0 -> 4.3.0.0을 리디렉션하는 것과 같은 바인딩)이있는 해당 .config 파일이 있는지 확인하십시오. 전자는 VS2012 상자에 후자가있는 반면).

+0

답장을 보내 주셔서 감사합니다. 실제로 GUI를 사용할 때 매핑이 문제가 될 수 있다는 경고가 있습니다. 그러나 테스트는 GUI에서 작동합니다. (저는 현재 그것을 고치고 있습니다.) 그러나 buildcommand는 경고없이 프로젝트를 깨끗하게 컴파일합니다 (F # 2와 F # 3 모두). 경고의 부족으로 매핑이 여전히 문제가 될 수 있습니까? 다시 한번 감사드립니다. –