2016-09-30 2 views
1

OCamlMake를 사용하여 현재 빌드 된 OCaml 프로젝트가 있습니다. 모든 빌드 아티팩트를 소스 파일과 동일한 디렉토리에 남겨두기 때문에 현재 빌드 시스템에 만족스럽지 않으며 모듈 들간의 종속성 순서를 수동으로 지정해야합니다. 이 문제로 고생하지 않는 빌드 시스템으로 전환하고 싶습니다. 나는 오아시스에 시도를하기로 결정했지만 문제가 발생했습니다.ocamlbuild와의 종속 된 종속성

프로젝트가 매우 구체적인 방법으로 만들어 졌기 때문에 문제가 발생합니다. 여러 다른 데이터베이스 백엔드 (PostgreSQL, MySQL, SQLite)를 지원합니다. 현재 데이터베이스 백엔드를 컴파일하려면 백엔드에서 필요로하는 추가 라이브러리를 설치하고 환경 변수를 설정하여 사용 가능하게해야합니다. 이것은 Makefile에서 보는 방법입니다.

ifdef MYSQL_LIBDIR 
    DB_CODE += mysql_database.ml 
    DB_AUXLIBS += $(MYSQL_LIBDIR) 
    DB_LIBS += mysql 
endif 

또한 모듈이 컴파일 된 모듈 목록에 추가됩니다. 중요한 점은 응용 프로그램 시작 지점에서 도달 할 수있는 모듈과 데이터베이스 백엔드 모듈 간의 종속성 (모듈 가져 오기 관점에서)이 없다는 것입니다. 오히려 각 데이터베이스 백엔드 모듈에는 모듈이 시작될 때 실행되는 최상위 코드가 포함되어 있으며 부작용을 사용하여 주 응용 프로그램에 등록됩니다.

이 설정을 오아시스에서 사용할 수 없습니다.

Library mysql-backend 
    Path   : . 
    Build  $: flag(mysql) 
    Install  : false 
    BuildTools : ocamlbuild 
    BuildDepends : main, mysql 
    Modules  : Mysql_backend 

그러나, 나는 실행에 옵션 모듈을 연결하는 오아시스를 알 수있는 방법을 알아낼 수 없습니다 : 나는 플래그와 함께 컴파일에 사용할 수있는 별도의 라이브러리로 데이터베이스 백엔드 모듈의 각을 선언했다. myocamlbuild.ml 파일을 수정하여이 작업을 수행하는 방법을 찾아 냈지만 실패했습니다. here라고 표시된 rule 함수를 사용하여이를 수행 할 수 있습니까?

ocamlbuild으로 설명 할 수 없다면 OCamlMake의 문제를 피하고 피할 수있는 도구가 있습니까?

답변

1

글쎄, 나는 답이 있다고 생각한다. 아래는 독창적 인 ocamlbuild 솔루션입니다. Drup 's와 본질적으로 같습니다.그 경로는 (확장)없이 파일 plugin.config에 나열된 모든 모듈에 의존 할 것이다 ocamlbuild 대상에서 태그 link_with_plugin 사용

open Ocamlbuild_plugin 

let enable_plugin() = 
    let plugins = try string_list_of_file "plugin.config" with _ -> [] in 
    dep ["ocaml"; "link_with_plugin"; "byte"] 
    (List.map (fun p -> p^".cmo") plugins); 
    dep ["ocaml"; "link_with_plugin"; "native"] 
    (List.map (fun p -> p^".cmx") plugins); 
() 

let() = dispatch begin 
    function 
    | Before_rules -> enable_plugin() 
    | _ ->() 
end 

. 예를 들어, 플러그인 pluga.ml, plugb.ml 및 파일 main.ml이있는 경우 plugin.configpluga plugb을 작성하고 <main.{cmo,cmx}>: link_with_plugin을 갖는 경우 두 가지 플러그인 모듈이 기본 실행 파일에 링크됩니다.

+0

문제가 어떻게 해결되는지 잘 모르겠습니다. 문제는 선택적 종속성을 구현하는 방법이었습니다. 객체 섹션에서이 문제를 해결하지 못하면 호스트 프로그램에서 명시 적으로 종속성을 지정해야합니다. 기본적으로, 문제는 컴파일 레벨에서 다형성을 구현하는 방법이었습니다. 동일한 인터페이스지만 다른 구현으로 라이브러리를 대체 할 수있을 때였습니다. – ivg

+0

아아, 알겠습니다. myocamlbuild 플러그인에서 조건부 연결을 구현했습니다. 약간 hardcodish,하지만 작동해야합니다. 이상적으로, 우리는 이것을 오아시스에 다시 기고해야합니다. PR이 PoC이므로 작동 할 수 있습니다. :) – ivg

0

불행히도, 이것은 오아시스 기능을 넘어선 것입니다. 이 제한은 ocamlbuild과 아무 관련이 없습니다. 단지 oasis 작성자가 간단하게 유지하려고했기 때문에 선택적 종속성을 기능으로 제공하지 않았기 때문입니다.

항상 그렇듯이 추가 수준의 간접 지정으로 문제가 해결 될 수 있습니다. 필요한 것은 사용자가 제공 한 매개 변수에 따라 _oasis 파일을 생성하는 구성 스크립트 (configure)입니다.

예를 들어 our project에는 구성 단계에서 사용자가 선택할 수있는 유사한 여러 설정 즉, 여러 개의 다른 백엔드가 있습니다 (--{enable,disable}-<feature>). 구성에 따라 _oasis 파일을 생성하는 자체 ./configure 스크립트를 작성하여이 작업을 수행했습니다. 구성 스크립트는 oasis 폴더에 설명 된대로 파일의 결과 인 _oasis을 연결합니다.

또 다른 해결책은 m4 또는 cpp을 사용하고 _oasis.in 파일을 사전 처리하는 것입니다. https://github.com/links-lang/links/pull/77 :

+0

제한 사항이'ocamlbuild'와 아무런 관련이 없다면 어떻게 든 myocamlbuild.ml을 사용하여 원하는 것을 얻을 수 있습니까? –

+0

나는이 두 가지 도구를 혼동스럽게 생각한다고 생각합니다. 'myocamlbuild.ml'은 ocamlbuild의 플러그인입니다. 'ocamlbuild'는 주어진 래서 피에서 물건을 만드는 법을 알고있는 컴파일 드라이버입니다. 플러그인에서'ocamlbuild'에게 새로운 것들 (예 : latex, C++, 전처리)을 만드는 법을 가르쳐 줄 수 있습니다. 'ocamlbuild'는 프로젝트를 설명하는 데 사용되지 않습니다. Makefile이나'mlpack'을 사용하여 수동으로 프로젝트를 기술 할 수 있습니다. – ivg

+0

ivg : 오아시스 파일을 사전 처리하는 것은 아마도 작업을 수행하는 최악의 방법 일 수 있습니다. 오아시스에 의존하는 빌드 시스템을 만듭니다. 더 나은 솔루션에 대한 내 대답을 참조하십시오. – Drup

1

내가 질문을보고 내가 위에서 Drup의 답변을 발견하기 전에 작업을 시작 :

관련 문제