2017-02-23 4 views
2

Crystal의 C interop 기능을 실험하고 싶었 기 때문에 C에서 작은 POC 라이브러리를 작성했습니다. 라이브러리를 C 프로그램에 연결하여 사용할 수 있습니다. 내 수정 프로그램에서 링크하려고 할 때, (crystal build src/c-interop.cr --verbose를 사용하여 구축), 나는 다음과 같은 오류를 만났다 해요 :크리스탈 프로그램에서 정적 C 라이브러리에 연결하는 데 문제가 있습니다.

λ crystal build src/c-interop.cr --verbose          
cc -o "/home/peter/projects/c-interop/c-interop" "${@}" -rdynamic --static -I/home/peter/projects/c-interop/c/include -L/home/peter/projects/c-interop/c/lib -lhello -lpcre -lgc -lpthread /opt/crystal/src/ext/libcrystal.a -levent -lrt -ldl -L/usr/lib -L/usr/local/lib _main.o S-lice40U-I-nt841.o P-ointer40U-I-nt841.o A-rgumentE-rror.o C-allS-tack.o A-rray40P-ointer40V-oid4141.o P-ointer40P-ointer40V-oid4141.o E-xception.o P-ointer40L-ibU-nwind5858E-xception41.o U-I-nt64.o U-I-nt8.o A-rray40S-tring41.o P-ointer40S-tring41.o I-nt32.o P-ointer40V-oid41.o F-iber.o T-hread.o S-et40T-hread41.o H-ash40T-hread4432N-il41.o P-ointer40H-ash58-5c8fd5776cf345ec94b91bf7a5f7e50f.o A-rray40I-nt3241.o S-tring5858B-uilder.o S-tring.o G-C-.o S-lice40T-41.o I-O-5858E-ncoder.o I-conv.o M-ath.o I-ndexE-rror.o E-rrno.o S-taticA-rray40U-I-nt2441.o C-har.o S-taticA-rray40U-I-nt84432441.o I-nvalidB-yteS-equenceE-rror.o S-taticA-rray40U-I-nt844326541.o D-ivisionB-yZ-ero.o P-ointer40I-nt3241.o U-I-nt32.o H-ash5858E-ntry40T-hread4432N-il41.o N-il.o D-eque40F-iber41.o P-ointer40F-iber41.o E-vent5858B-ase.o I-O-5858F-ileD-escriptor.o S-cheduler.o L-ibE-vent25858E-ventF-lags.o I-O-5858F-ileD-escriptor43.o E-vent5858E-vent.o I-nt64.o I-O-5858E-rror.o I-O-5858T-imeout.o E-xception43.o F-ile.o C-har5858R-eader.o R-ange40B-4432E-41.o R-ange40I-nt324432I-nt3241.o D-ebug5858E-L-F-.o D-ebug5858E-L-F-5858E-rror.o D-ebug5858E-L-F-5858E-ndianness.o D-ebug5858E-L-F-5858O-S-A-B-I-.o S-taticA-rray40U-I-nt84432409641.o I-O-5858E-O-F-E-rror.o D-ebug5858E-L-F-5858I-dent.o U-I-nt16.o I-O-5858B-yteF-ormat5858B-igE-ndian.o S-taticA-rray40U-I-nt84432241.o I-O-5858B-yteF-ormat5858L-ittleE-ndian.o D-ebug5858E-L-F-5858K-lass.o S-taticA-rray40U-I-nt84432841.o A-rray40D-ebug5858E-L-F-5858S-ectionH-eader41.o P-ointer40D-ebug5858E-L-F-5858S-ectionH-eader41.o I-O-5858S-eek.o D-ebug5858E-L-F-5858S-ectionH-eader.o I-O-5858D-ecoder.o D-ebug5858D-W-A-R-F-5858L-ineN-umbers.o A-rray40A-rray40D-d5580c0e9cb0bd8af7e90c96221706e1.o P-ointer40A-rray4-6533bdad81433bcf155b99ac74756686.o D-ebug5858D-W-A-R-F-5858L-ineN-umbers5858S-equence.o A-rray40T-uple40S-5992430a1a7ef1627717adfb71332538.o P-ointer40T-uple4-13415771527eed75ea796bf4f3711255.o A-rray40U-I-nt841.o I-nt8.o S-taticA-rray40U-I-nt84432141.o D-ebug5858D-W-A-R-F-.o D-ebug5858D-W-A-R-F-5858L-ineN-umbers5858R-egister.o D-ebug5858D-W-A-R-F-5858L-ineN-umbers5858R-ow.o A-rray40D-ebug585-1d195a7f864d2d3790ebeadd84b7a4df.o P-ointer40D-ebug5-a50eac5c43900f6bca76f68ff8c8549d.o D-ebug5858D-W-A-R-F-5858L-N-E-.o D-ebug5858D-W-A-R-F-5858L-N-S-.o P-roc40F-iber4432-6eb246a0a45118d3c5507cc830b14a70.o S-ignal.o P-roc40I-nt324432V-oid41.o E-vent5858S-ignalH-andler.o H-ash40S-ignal4432P-roc40S-ignal4432N-il4141.o P-ointer40H-ash58-ac8d12c9042874d67c1e049ddde35350.o H-ash5858E-ntry40-37a9b13947932e73bc9389d755897071.o E-vent5858S-ignalC-hildH-andler.o H-ash40I-nt324432P-rocess5858S-tatus41.o P-ointer40H-ash58-0a6eee72af0923261bdd3b6c7958da85.o H-ash40I-nt324432-12de0ef574784dde6ffe5b3ae93d5bba.o P-ointer40H-ash58-1ce4187043ca1e746f24acb8d0ff7a7e.o P-rocess5858S-tatus.o C-hannel5858B-uff-35976990a41c6a8201ab74e37227bdef.o C-hannel5858C-losedE-rror.o D-eque40P-rocess5858S-tatus3212432N-il41.o P-ointer40P-rocess5858S-tatus3212432N-il41.o H-ash5858E-ntry40-8e9a3cfcf19f0b3833711caadc35e784.o H-ash5858E-ntry40I-nt324432P-rocess5858S-tatus41.o I-O-.o S-taticA-rray40I-nt324432241.o A-tE-xitH-andlers.o A-rray40P-roc40I-nt324432N-il4141.o P-ointer40P-roc40I-nt324432N-il4141.o C-5858I-nterop.o L-E-B-R-eader.o L-ibU-nwind5858A-ction.o L-ibU-nwind5858R-easonC-ode.o C-allS-tack5858R-epeatedF-rame.o 
/opt/crystal/embedded/lib/../lib/libevent.a(evutil.o): In function `test_for_getaddrinfo_hacks': 
evutil.c:(.text+0x1488): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking 
/opt/crystal/embedded/lib/../lib/libevent.a(evutil.o): In function `evutil_unparse_protoname': 
evutil.c:(.text+0xf0d): warning: Using 'getprotobynumber' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking 

내 크리스탈 파일은 다음과 같습니다

@[Link(ldflags: "--static -I./c/include -L./c/lib -lhello")] 
lib LibHello 
    fun hello(name: UInt8*) : Void 
end 

module C::Interop 
    def self.hello(name) 
    LibHello.hello name 
    end 
end 

C::Interop.hello "world" 

내 프로젝트의 파일 다음과 같이 계층 구조는 다음과 같습니다

├── c 
│   ├── include 
│   │   └── hello.h 
│   └── lib 
│    ├── hello.c 
│    ├── hello.o 
│    └── libhello.a 
├── LICENSE 
├── README.md 
├── shard.yml 
├── spec 
│   ├── c-interop_spec.cr 
│   └── spec_helper.cr 
└── src 
    ├── c-interop 
    │   └── version.cr 
    └── c-interop.cr 
+0

'ld'의 오류 메시지에 액세스 할 수 있습니까? 'crystal build src/c-interop.cr --verbose' 또는'cc -o "/ home/peter/projects/c-interop/c-interop" "$ {@}"-rdynamic -static -I를 사용하십시오./c/include -L./c/lib -lhello -lpcre -lgc -lpthread /opt/crystal/src/ext/libcrystal.a -levent -lrt -ldl -L/usr/lib -L/usr/local/lib' 스스로? – Stargateur

+0

@Stargateur 업데이트되었습니다. – pdoherty926

답변

3

--static 플래그는 정적 링커가 마음에 들지 않는, libc의 연결 시도를 포함하여 전체 연결 단계에 영향을 미치고있다.

단일 라이브러리를 정적으로 링크하려면 .a 파일 (일반적으로 make 또는 다른 C 빌드 도구 사용)을 만들고 @[Link] 주석에 경로를 지정해야합니다. 상대 경로는 다음과 같이 지정할 수 있습니다 : @[Link(ldflags: "#{__DIR__}/ext/sgp4.a")].

예제 프로젝트는 빌드 된 C 라이브러리에서 정적으로 링크되는 predict.cr입니다.