Проблема со связью со статической библиотекой C в программе Crystal

Я хотел поэкспериментировать с возможностями взаимодействия C в Crystal, поэтому я написал небольшую POC-библиотеку на C. Я могу связать библиотеку с C-программой и использовать ее. Тем не менее, когда я пытаюсь связаться с ним из моей программы Crystal (построена с использованием crystal build src/c-interop.cr --verbose), Я столкнулся со следующей ошибкой:

λ 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-nt84432102441.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

Мой файл Crystal:

@[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

1 ответ

Решение

--static Флаг влияет на всю стадию компоновки, включая попытку статически связать libc, что компоновщику не нравится.

Чтобы статически связать одну библиотеку, вы должны создать .a файла (обычно используя make или какой-либо другой инструмент для сборки C), и укажите его путь в @[Link] аннотаций. Относительные пути можно указать так: @[Link(ldflags: "#{__DIR__}/ext/sgp4.a")],

Примером проекта мог бы стать файл gnast.cr, который статически связывает встроенную библиотеку Си.

Другие вопросы по тегам