Chạy chương trình Haskell trên HĐH Android


216

Forenote: Đây là phần mở rộng của chuỗi bắt đầu vào / r / haskell

Hãy bắt đầu với sự thật:

  • Android là một hệ điều hành tuyệt vời
  • Haskell là ngôn ngữ lập trình tốt nhất trên hành tinh

Do đó, rõ ràng, kết hợp chúng sẽ giúp phát triển Android tốt hơn nhiều. Vì vậy, về cơ bản tôi chỉ muốn biết làm thế nào tôi có thể viết các chương trình Haskell cho HĐH Android. Câu hỏi của tôi là:

Làm cách nào tôi có thể có được chương trình Haskell để thực thi / chạy trên HĐH Android?

Câu trả lời:


81

Cách bạn thực hiện là trước tiên hãy có một trình biên dịch Haskell có thể nhắm mục tiêu C với NDK của Android đi kèm với cổng GCC cho các kiến ​​trúc ARM. JHC có thể làm điều này một cách tầm thường với một tệp kiểu inf rất nhỏ mô tả nền tảng (kích thước từ, trình biên dịch c, v.v.) Tôi đã thực hiện điều này với bộ công cụ phát triển homebrew của Wii và nó khá dễ dàng. Tuy nhiên jhc vẫn có một số vấn đề ổn định với mã phức tạp như sử dụng ngăn xếp biến áp đơn nguyên với IO nhưng jhc đã được cải thiện rất nhiều trong 6 tháng qua. Chỉ có một người làm việc trên JHC, tôi chỉ ước có nhiều người có thể giúp anh ta.

Tùy chọn khác là xây dựng một cổng GHC "chưa đăng ký" nhắm mục tiêu vào ndk gcc, đây là quá trình liên quan nhiều hơn vì GHC không phải là trình biên dịch chéo thực sự vào lúc này và bạn cần hiểu hệ thống xây dựng những phần bạn cần thay đổi. Một tùy chọn khác là NHC có thể biên dịch chéo thành C, như GHC bạn cần xây dựng nhc nhắm mục tiêu trình biên dịch C, NHC không có nhiều tiện ích mở rộng Haskell như GHC.

Khi bạn có trình biên dịch Haskell nhắm mục tiêu NDK GCC, bạn sẽ cần phải viết các ràng buộc vào khung mã keo dán NDK JNI của Android (được thêm từ Android 2.3) hoặc bạn phải viết mã keo JNI giữa Java-C-Haskell, tùy chọn trước đây là dễ dàng hơn giải pháp và nếu tôi nhớ chính xác có thể thực sự tương thích ngược với các phiên bản Android trước đây dưới 2.3.

Khi bạn đã có thứ này, bạn phải xây dựng mã Haskell làm thư viện dùng chung hoặc thư viện tĩnh được liên kết với mã keo java NDK (bản thân nó là thư viện dùng chung). Theo như tôi biết, bạn không thể chính thức chạy các tệp thực thi gốc trên Android. Bạn có thể có thể làm điều đó với một điện thoại đã được root, vì vậy tôi cho rằng điều này có nghĩa là bạn không thể phân phối các tệp thực thi gốc trên cửa hàng ứng dụng ngay cả khi cổng gcc NDK có thể tạo ra các tệp thực thi gốc tốt. Điều này cũng có thể giết chết tùy chọn sử dụng LLVM trừ khi bạn có thể khiến NDK JNI hoạt động với LLVM.

Rào cản lớn nhất không phải là quá nhiều để có được trình biên dịch Haskell cho Android (vẫn còn là một trở ngại lớn) vấn đề lớn nhất là ai đó cần phải viết API ràng buộc cho các thư viện NDK, đây là một nhiệm vụ lớn và tình hình còn tồi tệ hơn nếu bạn cần phải viết mã giao diện người dùng Android vì không có API NDK cho phần này của SDK Android. Nếu bạn muốn làm mã UI Android trong Haskell, ai đó sẽ phải viết các liên kết Haskell với Java thông qua JNI / C. Trừ khi có một quy trình tự động hơn để viết thư viện ràng buộc (tôi biết có một số, chúng chỉ không đủ tự động cho tôi) thì khả năng một số người làm việc đó là khá thấp.

L01man: Có hướng dẫn về cách làm điều này không? Đối với phần đầu tiên, tôi hiểu rằng tôi phải tải xuống JHC. Tôi phải viết gì trong tập tin inf và làm thế nào để sử dụng nó?

Xin lưu ý trước khi tôi trả lời câu hỏi này. Tôi đã không sử dụng jhc trong một thời gian khá lâu kể từ khi tôi viết bài này và các phiên bản mới hơn đã được phát hành kể từ đó vì vậy tôi không biết jhc ổn định như thế nào khi nói đến việc tạo mã các chương trình Haskell phức tạp hơn. Đây là một cảnh báo cho bất cứ ai trước khi bạn xem xét thực hiện một chương trình Haskell lớn với JHC, bạn nên thực hiện một số thử nghiệm nhỏ trước khi bạn hoàn thành.

jhc có hướng dẫn sử dụng http://repetae.net/computer/jhc/manual.html và một phần về thiết lập biên dịch chéo và tệp .ini với các tùy chọn: http://repetae.net/computer/jhc/manual .html # chéo .

L01man: Phần thứ hai là một thay thế cho phần đầu tiên. Tôi không biết làm thế nào để làm những gì bạn nói trong phần ba.

Trước khi bắt đầu, bạn nên có một số kiến ​​thức về C và cảm thấy thoải mái khi sử dụng giao diện chức năng nước ngoài Haskell (FFI) và các công cụ như hs2c. Bạn cũng nên làm quen với việc sử dụng Android NDK và xây dựng .apk với các thư viện dùng chung. Bạn sẽ cần biết những điều này để giao diện giữa C-Haskell, Java / C-Haskell và phát triển các chương trình Haskell cho Android để bạn có thể phân phối / bán chính thức trên cửa hàng thị trường.

L01man: Tôi hiểu rằng mục tiêu của nó là tạo ra một ràng buộc cho API Android. Nhưng ... phần 4 có nói rằng chúng ta không thể tạo .apk bằng Haskell không?

.apk chỉ là một định dạng tệp gói ứng dụng và được xây dựng với các công cụ đi kèm với SDK Android (không phải NDK), điều này có rất ít để tự xây dựng các nhị phân. Các gói Android có thể chứa các thư viện dùng chung, đây là chương trình Haskell của bạn và các thư viện chia sẻ / tĩnh được tạo thông qua NDK của Android.


Tôi không có nghĩa là một chuyên gia Android. Nhưng hôm nay tôi đã bắt gặp lớp mới này được gọi là NativeACtivity kể từ API cấp 9 developer.android.com/reference/android/app/NativeActivity.html . Họ nói rằng nó có thể được sử dụng để thực hiện các hoạt động hoàn toàn bằng mã gốc. Tôi tự hỏi làm thế nào có liên quan / hữu ích cho mục đích của chúng tôi? Điều này có nghĩa là không cần tương tác giữa Haskell và Java?
Phil

@Po NativeActivity là một phần của khung mã keo dán NDK của Android (android 2.3) mà tôi đã viết về nó. Nó sẽ cho phép bạn viết tất cả mã của mình bằng C / C ++ nhưng bạn sẽ không có tệp thực thi riêng, bạn sẽ có một thư viện dùng chung được gọi từ Java. Nếu bạn đã viết các liên kết Haskell với NativeActivity, bạn sẽ không cần phải viết các liên kết giữa Java & Haskell nhưng như tôi đã đề cập API NDK là tập hợp con của API Java đầy đủ, không có API gốc cho giao diện người dùng Android tiêu chuẩn, ví dụ như bạn sẽ có để viết riêng của bạn trong OpenGL (ES) hoặc viết các ràng buộc JNI-Haskell.
snk_kid

Có một hướng dẫn về cách làm điều này?
L01man

Đối với phần đầu tiên, tôi hiểu rằng tôi phải tải xuống JHC. Tôi phải viết gì trong tập tin inf và làm thế nào để sử dụng nó? Phần thứ hai là một thay thế cho phần đầu tiên. Tôi không biết làm thế nào để làm những gì bạn nói trong phần ba. Tôi hiểu rằng mục tiêu của nó là tạo ra một ràng buộc cho API Android. Nhưng ... phần 4 có nói rằng chúng ta không thể tạo .apk bằng Haskell không?
L01man

@ L01man Tôi đã trả lời câu hỏi của bạn trong câu trả lời chính vì giới hạn ký tự trong các nhận xét.
snk_kid

16

https://github.com/neurocyte/android-haskell-activity chứng minh Haskellmã đang chạy.


4
Con trai của một ... ai đó thực sự đã làm điều đó! Thanh danh.
Robert Massaioli

Tôi sẽ xem xét kỹ hơn về điều này sớm. Nếu nó có vẻ hợp pháp thì tôi sẽ thay đổi câu trả lời được đánh dấu cho câu hỏi này.
Robert Massaioli

Robert, nó có vẻ hợp pháp. Nhưng tế bào thần kinh dường như không cung cấp hướng dẫn chi tiết về bản dựng. Đọc github.com/neurocyte/android-haskell-activity/issues/1
gliptak

16

Một ngôn ngữ gần đây đã được tôi chú ý là Eta .

Trình biên dịch của Eta là một nhánh của GHC 7.10 có phụ trợ JVM. Có thể sử dụng các tệp JAR được tạo để viết ứng dụng Android và thậm chí sử dụng Giao diện chức năng nước ngoài của nó để gọi các thư viện Java gốc.

Brian McKenna đã viết một bài đăng trên blog về cách định cấu hình dự án Android Studio để sử dụng thư viện Eta .


9

Tôi đã từng bắt gặp cùng một chủ đề Reddit, nhưng nó đã cũ và các bình luận đã bị đóng. Tôi đã gửi tin nhắn cho OP, nhưng tôi không chắc liệu nó có đến được người nhận hay không. Đề xuất của tôi ở đây (có thể hoạt động cho các Android cũ hơn, nơi các hoạt động gốc không thể thực hiện được).

Tôi (đã phát triển ở Haskell một thời gian trước đây, nhưng hiện tại đã chuyển sang Smalltalk) hiện đang phát triển một cổng Squeak VM sang Android. Cách tôi đang làm điều này tương tự như những gì có thể được xử lý trong một dự án haskell-on-android: một đoạn mã C cần được gọi từ một phần của ứng dụng Java (về cơ bản tất cả những gì có thể được thực hiện trong Android là xử lý các sự kiện khác nhau, một ứng dụng không thể tự thăm dò các sự kiện và không có bất kỳ vòng lặp sự kiện nào). Trong trường hợp của tôi, mã được tạo bởi các công cụ xây dựng Squeak VM, trong trường hợp haskell trên Android, đây sẽ là đầu ra từ GHC của JHC hoặc bất kỳ giao diện người dùng nào được sử dụng. Repo này có thể đáng xem:

http://gitorious.org/~golubovsky/cogvm/dmg-blished/trees/master/pl platforms / android / project

Trong "src" có mã Java cung cấp chức năng chặn sự kiện của người dùng và gửi chúng đến mã gốc (xem lớp CogView). Bản thân mã C của VM không hoàn toàn ở đó (xem squeakvm.org, nhánh Cog cho điều đó), nhưng người ta có thể có ý tưởng. Người ta cũng có thể xem dưới http://gitorious.org/~golubovsky/cogvm/dmg-blished/trees/master/pl platforms / android / vm , là tiền đề C cho trình thông dịch (bao gồm cả xử lý sự kiện của người dùng, một số chấm công, v.v. )

Hi vọng điêu nay co ich.

Dmitry



6

Tôi nghĩ rằng câu trả lời chung nên đến từ các biến đổi nguồn-> nguồn, vì việc tải các đối tượng chia sẻ được biên dịch đặc biệt dường như là một chút bùn (liên quan đến ghc-> c và bước c-> java trong các câu trả lời ở trên). Do đó, câu hỏi này nằm dưới tiêu đề của Haskell trên JVM, đã được thử (với một bước là biểu diễn trung gian Java) và được thảo luận dài. Bạn có thể sử dụng frege nếu các thư viện bạn cần biên dịch ở đó. Các bước duy nhất còn lại sẽ là sự khởi đầu của API khung Android được dịch thành các hành động IO () và có thể là một trình bao bọc để xây dựng xml và apk tệp kê khai.


1
Trên thực tế, tồn tại một ứng dụng Android giới thiệu được viết bằng Java và Frege, chi tiết có ở đây Groups.google.com/forum/#!topic/frege-programming-lingu/iêu
Ingo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.