Jak włączyć istniejący plik make z Androidem NDK

Mam więc ogromny istniejący projekt C, który umieściłem w katalogu $PROJECT/jni. Ten projekt jest zwykle tworzony przez uruchomienie skryptu configure, który tworzy pliki Makefile, które następnie pozwalają na kompilację projektu za pomocą make.

Ten projekt jest dość duży i ma wiele katalogów zawierających pliki źródłowe i pliki nagłówkowe.

Myślę, że brakuje mi tutaj fundamentalnego zrozumienia, jak Android.mk ma działać. Czy ma zastąpić configure i makefile, który jest obecnie używany do kompilacji projektu? Czy Mogę włączyć wygenerowany plik makefile z mojego skryptu configure do Android.mk? Przykłady, które dostarczają, są dość trywialne z tylko kilkoma plikami źródłowymi. Mój katalog jni wygląda bardziej jak:

jni/
  folder1/subfolder1
  folder1/subfolder2
  folder1/source
  folder2/source
  .....
  foldern/source
  configure/
  configure/configure.sh
  Makefile
  Android.mk

Wygenerowane pliki Makefile są dość obszerne (duża ilość konfiguracji i jest jedna w każdym katalogu), więc nie wiem, jak do tego podejść.

EDIT:

Głównym problemem jest to, że przykłady, które statek z NDK są trywialne przykłady. Mają 3-5 plików źródłowych w katalogu JNI najwyższego poziomu. Mój problem polega na tym, że jest to ogromny projekt ze złożoną konfiguracją z 4 folderami najwyższego poziomu, każdy z wieloma podkatalogami. Nie mogę po prostu przenieść źródła do folderu jni i uruchomić kompilatora NDK.

Author: thatidiotguy, 2013-06-27

3 answers

Aby odpowiedzieć na twoje pytanie, tak Android.mk jest systemem budowania Androida. Google ledwo wspomina, że "język"tego pliku jest zaimplementowany jako makra GNU. Dokumenty chcą, abyś opisał swój projekt pod kątem tych makr. Zajmują się wszystkimi szczegółami grungy cross-compilation. Jestem całkiem pewien, że Google zastosowało to podejście, aby poprawić przenośność plików Android.mk w miarę rozwoju narzędzi programistycznych.

Wynik jest taki, że (i Wiem, że nie będziesz chciał tego słuchać) najlepszą odpowiedzią jest prawdopodobnie napisanie odpowiedniego NDK Android.mk dla Twojego dużego projektu od podstaw.

Ten artykuł przedstawia te same spostrzeżenia, które zrobiłem portując bibliotekę około 800 plików i 300K SLOC. Niestety spaliłem prawie dwa tygodnie, dochodząc do tego samego wniosku: Cross-compilation powoduje, że przynajmniej niektóre skrypty configure zawodzą (skutkują błędnymi plikami config.h). "Wynalazłem" prawie te same techniki, których używa w artykule. Ale nawet po tym, jak mam czystą budowę, powstała Biblioteka statyczna nie działała w pełni. Godziny debugowania, brak użytecznych informacji. [Zastrzeżenie: nie jestem ekspertem od narzędzi konfiguracyjnych. Guru pewnie by zauważył mój błąd. Tak to wygląda. Kilka dni zajęło mi stworzenie czystego Android.mk. Powstała Biblioteka przeprowadziła wszystkie testy po raz pierwszy. I przeportował czysto przez kilka obrotów narzędzi programistycznych.

Niestety zbudowanie biblioteki, która używa configure bez narzędzi auto oznacza zbudowanie własnej config.h ręcznie dla docelowego środowiska. Może nie jest tak źle, jak się wydaje. Systemy IME mają tendencję do definiowania znacznie więcej w swoich środowiskach configure, niż w rzeczywistości używają. Uzyskanie jasnego wyobrażenia o rzeczywistych zależnościach może odwdzięczyć się żmudnym wysiłkiem podczas przyszłego refaktoryzacji.

Podsumowanie z artykułu mówi wszystko:

Autotool jest dobry tylko na systemach GNU i używanie go do kompilacji krzyżowej może być naprawdę żmudne, mylące, podatne na błędy lub nawet niemożliwe. Metoda opisane tutaj jest hack i powinny być używane na własne ryzyko.

Przepraszam, że nie mam bardziej pozytywnej sugestii.
 13
Author: Gene,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-06 03:48:45

Moja odpowiedź najlepiej współgra z odpowiedzią genu.

./configure'S tworzenie pliku konfiguracyjnego opiera się na kompilowaniu (i ewentualnie uruchamianiu) małych fragmentów kodu C dla każdego testu. Sukces każdego testu ustawia odpowiednią zmienną w szablonie config.h.in, Aby utworzyć config.h. Testy tylko kompilacji mogą być z powodzeniem testowane w środowisku cross-compile. Jednak testy Run compile i są niemożliwe do uruchomienia w środowisku cross-compile.

Tak więc, aby rozpocząć proces konwersji, musisz ustawić zmienne środowiskoweCPP,CC,LD i inne aliasy narzędzi do zestawu narzędzi kompilatora krzyżowego (prawdopodobnie te z NDK), a następnie uruchom ./configure. Gdy to zrobisz, będziesz musiał skorygować config.h, aby dopasować się do docelowego środowiska. To jest twój najbardziej krytyczny i najbardziej podatny na błędy krok.

Jeśli chodzi o Android.mk, jest to format zbliżony do Makefile.am, który można łatwo przekształcić. Możesz zignorować Makefile.in i Makefile, ponieważ są one generowane z Makefile.am.

Aby wziąć przykład pliku (Wersja 5.11), uruchomiłem konfigurację z następującymi opcjami,
./configure --host arm-toshiba-linux-androideabi --build x86_64-linux-gnu \
            --prefix=/data/local/ host_alias=arm-linux-androideabi \
           "CFLAGS=--sysroot=~/ndk/platforms/android-8/arch-arm  -Wall -Wextra" \
           "CPPFLAGS=--sysroot=~/ndk/platforms/android-8/arch-arm" \
            CPP=arm-linux-androideabi-cpp

Następnym krokiem było wykonanie src/Makefile.am Jak poniżej:

MAGIC = $(pkgdatadir)/magic
lib_LTLIBRARIES = libmagic.la
include_HEADERS = magic.h

bin_PROGRAMS = file

AM_CPPFLAGS = -DMAGIC='"$(MAGIC)"'
AM_CFLAGS = $(CFLAG_VISIBILITY) @WARNINGS@

libmagic_la_SOURCES = magic.c apprentice.c softmagic.c ascmagic.c \
        encoding.c compress.c is_tar.c readelf.c print.c fsmagic.c \
        funcs.c file.h readelf.h tar.h apptype.c \
        file_opts.h elfclass.h mygetopt.h cdf.c cdf_time.c readcdf.c cdf.h
libmagic_la_LDFLAGS = -no-undefined -version-info 1:0:0
if MINGW
MINGWLIBS = -lgnurx -lshlwapi
else
MINGWLIBS =
endif
libmagic_la_LIBADD = $(LTLIBOBJS) $(MINGWLIBS)

file_SOURCES = file.c
file_LDADD = libmagic.la
CLEANFILES = magic.h
EXTRA_DIST = magic.h.in
HDR= $(top_srcdir)/src/magic.h.in
BUILT_SOURCES = magic.h

magic.h:        ${HDR}
        sed -e "s/X.YY/$$(echo @VERSION@ | tr -d .)/" < ${HDR} > $@

I utwórz Android.mk z tego.

Ostatnim i najważniejszym krokiem było zmodyfikowanie config.h, aby dokładnie odzwierciedlić stan docelowego systemu. Będzie to proces ręczny, którego nie mogę dać obejście problemu, polegające głównie na zapoznaniu się z konfiguracją.Zaloguj się, przeglądając nagłówki i" wywołując " Google. Owoce tej pracy są dostępne na XDA.

 5
Author: Samveen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-08 01:41:12

Oto rozwiązanie do robienia rzeczy na odwrót: budowanie zarówno biblioteka zewnętrzna, jak i pakiet Android ze standardowych plików Makefiles.

Jako warunek konieczny, musisz zainstalować wszystko, co potrzebne do wykonania wiersza poleceń Rozwój Androida:

    W systemie Android NDK Można używać tylko jednego narzędzia.]}
  • ant.

Struktura przykładu jest następująca: katalog dla zewnętrznej biblioteki i katalog dla Androida źródła na tym samym poziomie z Makefile w każdym katalogu i najwyższym, rekurencyjnym pliku Makefile:

Makefile
mylib/
    Makefile
android/
    Makefile

mylib/Makefile buduje statyczną bibliotekę:

AR=/path/to/standalone/bin/arm-linux-androideabi-ar
CC=/path/to/standalone/bin/arm-linux-androideabi-gcc

libmylib.a: mylib.o
    $(AR) rcs libmylib.a mylib.o

mylib.o: mylib.c
    $(CC) -c mylib.c -o mylib.o

android/Makefile dostarcza reguły budowania pakietu Android:

  • potrzebujemy zależności do skopiowania mylib Kiedy zostanie zmodyfikowana;
  • W związku z tym, że system android nie jest w pełni funkcjonalny, nie jest w stanie go uruchomić.]}
  • pakiet android zależy od źródeł Java i od współdzielonego biblioteka.

Plik Makefile zapewnia dwa cele: release (domyślny) i debug do budowania pakietu release lub debugowania.

NDK_BUILD=/path/to/ndk-build
JAVASRC=src/com/example/ndkmake/NdkMake.java

release: bin/NdkMake-release-unsigned.apk

debug: bin/NdkMake-debug.apk

bin/NdkMake-release-unsigned.apk: libs/armeabi/libndkmake.so $(JAVASRC)
ant release

bin/NdkMake-debug.apk: libs/armeabi/libndkmake.so $(JAVASRC)
ant debug

libs/armeabi/libndkmake.so: jni/ndkmake.c jni/libmylib.a
$(NDK_BUILD)

jni/libmylib.a: ../mylib/libmylib.a
cp ../mylib/libmylib.a jni/libmylib.a

Plik Android.mk zawiera reguły dołączania statycznej biblioteki do kompilacji, jako prebuilt. Dołączamy nagłówki z biblioteki mylib używając LOCAL_EXPORT_C_INCLUDES.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := ndkmake
LOCAL_SRC_FILES := ndkmake.c
LOCAL_STATIC_LIBRARIES := mylib-prebuilt
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := mylib-prebuilt
LOCAL_SRC_FILES := libmylib.a
LOCAL_EXPORT_C_INCLUDES := ../mylib/
include $(PREBUILT_STATIC_LIBRARY)

Teraz potrzebujemy tylko pliku Makefile najwyższego poziomu, aby zbudować dwa podkatalogi:

all: libmylib package

libmylib:
    cd mylib && $(MAKE)

package:
    cd android && $(MAKE)

Wszelkie zmiany w bibliotece, źródłach jni lub źródłach Javy spowoduje odbudowę paczki.

 4
Author: Guillaume,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-08 07:43:46