LoginSignup
4
1

More than 5 years have passed since last update.

開発版Emacsバージョン26.0.91をビルドしてみた(Termux on Android)

Last updated at Posted at 2018-02-13

インストールしたところ、早速不具合が出てしまいました。原因はtermux-packagesのemacsパッケージ(emacs-25.3)のパッチを取り込む際に拡張子*.patchでないパッチを取り込み忘れたため、つまり自分のせいでした、すいません。本文のパッチは2018/02/21に修正しました。

Emacs26から導入される、一部で待望されていた行番号表示(実装者によると結構高速らしいです。ホントに不承不承といった感じが微笑ましいです。アンチニュースの執筆スタンスは100%シャレではないんだぜ?ということでしょう。かくいう自分は、実は待ってました。別に行番号が必要とかじゃなく、なんか見た目がカッコイーから。BasicやCOBOLの世代なんですよ、わたし)を試したくてTermuxでビルドしました。

基礎知識

わたしは特にAndroidとかに詳しくないので、Teruxマニュアルのパッケージ管理の手順が基本になります。つまり、

  1. ビルドツールのインストール
  2. ソースの入手と修正
  3. configureのための環境準備
  4. configureしてmake

...という流れになります。

なお、マニュアルには特に載ってませんがTermuxパッケージの公式リポジトリには、(多分)リポジトリのアプリをDocker上でビルドするために必要なpatchやスクリプトがあり、これらはTermuxでそのアプリをソースからビルドするとき、とても役にたちます。

前準備

ビルドツールのインストール

マニュアルにしたがい、ビルドツールをインストールします。

[~/src/emacs] pkg install autoconf automake bison bzip2 \
              clang cmake coreutils diffutils \
              flex gawk git grep gzip libtool \
              make patch perl sed silversearcher-ag \
              tar termux-exec wget
Hit:1 https://termux.net stable InRelease
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.
Reading package lists... Done
Building dependency tree
Reading state information... Done
.....

依存パッケージのインストール

公式リポジトリにはEmacs-25.3ビルド用のスクリプトがあります。それをダウンロードします。中を覗いてみるとncursesgnutlslibxml2というパッケージが必要らしいです。バージョンが違うので必要十分ではないでしょうが、とりあえずインストールしておきます。ただ、バイナリの実行だけでなくビルドから行いたいので、-devつきのパッケージ、つまりncurses-dev,gnutls-dev, libxml2-devをインストールします。

[~/src/emacs]$ pkg install ncurses-dev gnutls-dev libxml2-dev
Hit:1 https://termux.net stable InRelease
Reading package lists... Done
Building dependency tree
Reading state information... Done
.....

他にも、わたしの環境にはインストールしてあって、素のTermuxに入ってないパッケージが必要な場合にはconfigureやmakeでエラーが出るので、その場合は、そのパッケージをpkg installインストールして、configureからやり直せば大丈夫です。

ビルド

いよいよビルドしていきます。

ソースの取得

ソースのemacs-26.0.91.tar.gzをダウンロードして解凍し、そのフォルダに移動します。

[~/src/emacs]$ tar xvfz emacs-26.0.91.tar.gz 2>&1|head -20                                     emacs-26.0.91/                                                                            emacs-26.0.91/.dir-locals.el                                                              emacs-26.0.91/.gitattributes                                                              emacs-26.0.91/.gitignore                                                                  emacs-26.0.91/.gitlab-ci.yml                                                              emacs-26.0.91/BUGS                                                                        emacs-26.0.91/CONTRIBUTE                                                                  emacs-26.0.91/COPYING                                                                     emacs-26.0.91/ChangeLog.1                                                                 emacs-26.0.91/ChangeLog.2                                                                 emacs-26.0.91/ChangeLog.3                                                                 emacs-26.0.91/GNUmakefile
.....
[~/src/emacs]$ cd emacs-26.0.91
[~/src/emacs/emacs-26.0.91]

Termuxビルド環境の準備

Termuxでビルドするために、以下を行います。本来ならインストール先の--prefixには$PREFIXを指定するのですが、流石にそれは怖いので--prefix=$HOMEで行いました。そのためインストールしたEmacsを実行するためにPATH~/binも追加してます。

[~/src/emacs/emacs-26.0.91]$ export PREFIX=/data/data/com.termux/files/usr
[~/src/emacs/emacs-26.0.91]$ export LD_PRELOAD=${PREFIX}/lib/libtermux-exec.so
[~/src/emacs/emacs-26.0.91]$ export PATH=$HOME/bin:$PATH

ソース修正

patchによる修正を行います。以下のpatchファイルの内容の99%は公式リポジトリEmacsパッケージ*.patchから頂きました。

emacs-26.0.91.patch
diff -u -r ../emacs-26.0.91.orig/lib-src/emacsclient.c ./lib-src/emacsclient.c
--- ../emacs-26.0.91.orig/lib-src/emacsclient.c 2018-01-14 06:07:12.000000000 +0900
+++ ./lib-src/emacsclient.c 2018-02-20 14:00:42.209932042 +0900
@@ -1287,7 +1287,7 @@
               }
             else
 #endif
-              tmpdir = "/tmp";
+              tmpdir = "@TERMUX_PREFIX@/tmp";
           }
    socket_name_storage =
      xmalloc (strlen (tmpdir) + strlen (server_name) + EXTRA_SPACE);
diff -u -r ../emacs-26.0.91.orig/lib-src/pop.c ./lib-src/pop.c
--- ../emacs-26.0.91.orig/lib-src/pop.c 2018-01-14 06:07:12.000000000 +0900
+++ ./lib-src/pop.c 2018-02-20 14:00:42.209932042 +0900
@@ -71,6 +71,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <stdbool.h>

 #ifdef KERBEROS
 # ifdef HAVE_KRB5_H
@@ -129,6 +130,23 @@
 char pop_error[ERROR_MAX];
 bool pop_debug = false;

+#ifdef __ANDROID__
+static char* getpass(const char* prompt) {
+   printf("%s\n", prompt);
+   static char chars[128];
+   int len = 0;
+   while (true) {
+       char c = fgetc(stdin); 
+       if (c == '\r' || c == '\n' || c == 0) break; 
+       chars[len++] = c;
+       if (len == sizeof(chars)-1) break;
+   } 
+   chars[len] = 0;
+   return chars;
+}
+#endif
+
+
 /*
  * Function: pop_open (char *host, char *username, char *password,
  *                int flags)
diff -u -r ../emacs-26.0.91.orig/lisp/cus-start.el ./lisp/cus-start.el
--- ../emacs-26.0.91.orig/lisp/cus-start.el 2018-01-14 06:07:12.000000000 +0900
+++ ./lisp/cus-start.el 2018-02-20 14:23:37.279931517 +0900
@@ -284,12 +284,12 @@
                 (setq tmp (replace-regexp-in-string
                        "\n\\'" "" tmp))
                 ;; Handles "getconf: Unrecognized variable..."
-                (file-directory-p tmp)
+                (File-directory-p tmp)
                 tmp))
              "/tmp"))
             (t
              (or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP")
-             "/tmp"))))
+             "@TERMUX_PREFIX@/tmp"))))
          :initialize custom-initialize-delay)
         ;; fns.c
         (use-dialog-box menu boolean "21.1")
diff -u -r ../emacs-26.0.91.orig/lisp/international/ucs-normalize.el ./lisp/international/ucs-normalize.el
--- ../emacs-26.0.91.orig/lisp/international/ucs-normalize.el   2018-01-14 06:07:12.000000000 +0900
+++ ./lisp/international/ucs-normalize.el   2018-02-20 14:00:42.219932042 +0900
@@ -111,6 +111,9 @@

 (eval-when-compile (require 'cl-lib))

+;;; add for regexp-opt-charset
+(eval-when-compile (require 'regexp-opt))
+                   
 (declare-function nfd "ucs-normalize" (char))

 (eval-when-compile
diff -u -r ../emacs-26.0.91.orig/lisp/loadup.el ./lisp/loadup.el
--- ../emacs-26.0.91.orig/lisp/loadup.el    2018-01-14 06:07:12.000000000 +0900
+++ ./lisp/loadup.el    2018-02-20 14:30:30.789931359 +0900
@@ -393,7 +393,12 @@
       (message "Warning: Change in load-path due to site-init will be \
 lost after dumping")))

-(setq current-load-list nil)
+;; On an emacs that runs undumped, i.e. Android, this causes bogus 
+;; entries to appear in load-history. Commenting this out causes an entry
+;; for loadup.el with a bogus filename to appear instead, but since it
+;; neither provides nor requires anything, it appears to be safe.
+;;(setq current-load-list nil)
+
 ;; Avoid storing references to build directory in the binary.
 (setq custom-current-group-alist nil)

@@ -453,7 +458,10 @@
       ;; Mainly cosmetic, but helpful for Guix.  (Bug#20330)
       ;; Do this here, rather than earlier, so that the above code
       ;; can invoke Git commands and the like.
-      (setq exec-path nil)
+      
+      ;; Termux patch: Keep exec-path when running undumped:
+      ;; (setq exec-path nil)
+
       (message "Dumping under the name emacs")
       (condition-case ()
      (delete-file "emacs")
diff -u -r ../emacs-26.0.91.orig/lisp/net/tramp.el ./lisp/net/tramp.el
--- ../emacs-26.0.91.orig/lisp/net/tramp.el 2018-01-14 06:07:12.000000000 +0900
+++ ./lisp/net/tramp.el 2018-02-20 14:32:40.759931310 +0900
@@ -127,7 +127,7 @@
   :require 'tramp)

 (defcustom tramp-encoding-shell
-  (or (tramp-compat-funcall 'w32-shell-name) "/bin/sh")
+  (or (tramp-compat-funcall 'w32-shell-name) "@TERMUX_PREFIX@/bin/sh")
   "Use this program for encoding and decoding commands on the local host.
 This shell is used to execute the encoding and decoding command on the
 local host, so if you want to use `~' in those commands, you should
diff -u -r ../emacs-26.0.91.orig/lisp/server.el ./lisp/server.el
--- ../emacs-26.0.91.orig/lisp/server.el    2018-01-14 06:07:12.000000000 +0900
+++ ./lisp/server.el    2018-02-20 14:35:42.759931240 +0900
@@ -226,7 +226,7 @@
         (function-item :tag "Use pop-to-buffer" pop-to-buffer)
         (function :tag "Other function")))

-(defcustom server-temp-file-regexp "^/tmp/Re\\|/draft$"
+(defcustom server-temp-file-regexp "^@TERMUX_PREFIX@/tmp/Re\\|@TERMUX_PREFIX@/draft$"
   "Regexp matching names of temporary files.
 These are deleted and reused after each edit by the programs that
 invoke the Emacs server."
@@ -264,7 +264,7 @@
 ;; does not read the init file.
 (defvar server-socket-dir
   (and (featurep 'make-network-process '(:family local))
-       (format "%s/emacs%d" (or (getenv "TMPDIR") "/tmp") (user-uid)))
+       (format "%s/emacs%d" (or (getenv "TMPDIR") "@TERMUX_PREFIX@/tmp") (user-uid)))
   "The directory in which to place the server socket.
 If local sockets are not supported, this is nil.")

diff -u -r ../emacs-26.0.91.orig/lisp/subr.el ./lisp/subr.el
--- ../emacs-26.0.91.orig/lisp/subr.el  2018-01-14 06:07:12.000000000 +0900
+++ ./lisp/subr.el  2018-02-20 14:37:40.379931196 +0900
@@ -3142,7 +3142,7 @@
   (declare (advertised-calling-convention (name buffer command) "23.1"))
   (start-file-process
    name buffer
-   (if (file-remote-p default-directory) "/bin/sh" shell-file-name)
+   (if (file-remote-p default-directory) "@TERMUX_PREFIX@/bin/sh" shell-file-name)
    (if (file-remote-p default-directory) "-c" shell-command-switch)
    (mapconcat 'identity args " ")))

@@ -3186,7 +3186,7 @@
   (declare (advertised-calling-convention
             (command &optional infile buffer display) "24.5"))
   (process-file
-   (if (file-remote-p default-directory) "/bin/sh" shell-file-name)
+   (if (file-remote-p default-directory) "@TERMUX_PREFIX@/bin/sh" shell-file-name)
    infile buffer display
    (if (file-remote-p default-directory) "-c" shell-command-switch)
    (mapconcat 'identity (cons command args) " ")))
diff -u -r ../emacs-26.0.91.orig/lisp/term.el ./lisp/term.el
--- ../emacs-26.0.91.orig/lisp/term.el  2018-01-14 06:07:12.000000000 +0900
+++ ./lisp/term.el  2018-02-20 14:40:45.919931125 +0900
@@ -1538,7 +1538,7 @@
    ;; do the decoding by hand on the parts that are made of chars.
    (coding-system-for-read 'binary))
     (apply 'start-process name buffer
-      "/bin/sh" "-c"
+      "@TERMUX_PREFIX@/bin/sh" "-c"
       (format "stty -nl echo rows %d columns %d sane 2>/dev/null;\
 if [ $1 = .. ]; then shift; fi; exec \"$@\""
           term-height term-width)
diff -u -r ../emacs-26.0.91.orig/src/Makefile.in ./src/Makefile.in
--- ../emacs-26.0.91.orig/src/Makefile.in   2018-01-14 06:07:12.000000000 +0900
+++ ./src/Makefile.in   2018-02-20 14:00:42.219932042 +0900
@@ -532,7 +532,8 @@
                 lisp.mk $(etc)/DOC $(lisp) \
                 $(lispsource)/international/charprop.el ${charsets}
 ifeq ($(CANNOT_DUMP),yes)
-   ln -f temacs$(EXEEXT) $@
+   rm -f $@
+   ln -s temacs$(EXEEXT) $@
 else
    LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup dump
   ifneq ($(PAXCTL_dumped),)
@@ -736,7 +737,8 @@
 bootstrap-emacs$(EXEEXT): temacs$(EXEEXT)
    $(MAKE) -C ../lisp update-subdirs
 ifeq ($(CANNOT_DUMP),yes)
-   ln -f temacs$(EXEEXT) $@
+   rm -f  $@
+   ln -s temacs$(EXEEXT) $@
 else
    $(RUN_TEMACS) --batch $(BUILD_DETAILS) --load loadup bootstrap
   ifneq ($(PAXCTL_dumped),)
diff -u -r ../emacs-26.0.91.orig/src/callproc.c ./src/callproc.c
--- ../emacs-26.0.91.orig/src/callproc.c    2018-01-14 06:07:12.000000000 +0900
+++ ./src/callproc.c    2018-02-20 14:00:42.229932042 +0900
@@ -1612,7 +1612,7 @@
     dir_warning ("arch-independent data dir", Vdata_directory);

   sh = getenv ("SHELL");
-  Vshell_file_name = build_string (sh ? sh : "/bin/sh");
+  Vshell_file_name = build_string (sh ? sh : "@TERMUX_PREFIX@/bin/sh");

   Lisp_Object gamedir = Qnil;
   if (PATH_GAME)
diff -u -r ../emacs-26.0.91.orig/src/editfns.c ./src/editfns.c
--- ../emacs-26.0.91.orig/src/editfns.c 2018-01-14 06:07:12.000000000 +0900
+++ ./src/editfns.c 2018-02-20 14:00:42.229932042 +0900
@@ -1440,7 +1440,7 @@
   if (!pw)
     return Qnil;

-  p = USER_FULL_NAME;
+  p = "unknown";
   /* Chop off everything after the first comma. */
   q = strchr (p, ',');
   full = make_string (p, q ? q - p : strlen (p));
diff -u -r ../emacs-26.0.91.orig/src/filelock.c ./src/filelock.c
--- ../emacs-26.0.91.orig/src/filelock.c    2018-01-14 06:07:12.000000000 +0900
+++ ./src/filelock.c    2018-02-20 14:00:42.229932042 +0900
@@ -127,14 +127,14 @@
 static time_t boot_time;
 static bool boot_time_initialized;

-#ifdef BOOT_TIME
+#if defined(BOOT_TIME) && !defined(__ANDROID__)
 static void get_boot_time_1 (const char *, bool);
 #endif

 static time_t
 get_boot_time (void)
 {
-#if defined (BOOT_TIME)
+#if defined (BOOT_TIME) && !defined(__ANDROID__)
   int counter;
 #endif

@@ -170,7 +170,7 @@
    }
     }

-#if defined (BOOT_TIME)
+#if defined (BOOT_TIME) && !defined(__ANDROID__)
 #ifndef CANNOT_DUMP
   /* The utmp routines maintain static state.
      Don't touch that state unless we are initialized,
@@ -232,7 +232,7 @@
 #endif
 }

-#ifdef BOOT_TIME
+#if defined(BOOT_TIME) && !defined(__ANDROID__)
 /* Try to get the boot time from wtmp file FILENAME.
    This succeeds if that file contains a reboot record.

diff -u -r ../emacs-26.0.91.orig/src/keyboard.c ./src/keyboard.c
--- ../emacs-26.0.91.orig/src/keyboard.c    2018-01-14 06:07:12.000000000 +0900
+++ ./src/keyboard.c    2018-02-20 14:00:42.239932042 +0900
@@ -8916,7 +8916,6 @@
   ptrdiff_t keys_start;

   Lisp_Object current_binding = Qnil;
-  Lisp_Object first_event = Qnil;

   /* Index of the first key that has no binding.
      It is useless to try fkey.start larger than that.  */
@@ -9026,6 +9025,7 @@

   starting_buffer = current_buffer;
   first_unbound = bufsize + 1;
+  Lisp_Object first_event = mock_input > 0 ? keybuf[0] : Qnil;

   /* Build our list of keymaps.
      If we recognize a function key and replace its escape sequence in

このpatchファイルをどこかに作成して、ソースフォルダからpatchを適用します。

[~/src/emacs/emacs-26.0.91]$ perl -pe "s{\@TERMUX_PREFIX\@}{$PREFIX}g" ../emacs-26.0.91.patch | patch -p1
patching file lib-src/emacsclient.c
patching file lib-src/pop.c
patching file lisp/cus-start.el
patching file lisp/international/ucs-normalize.el
patching file lisp/loadup.el                                                       patching file lisp/net/tramp.el
patching file lisp/server.el
patching file lisp/subr.el
patching file lisp/term.el
patching file src/Makefile.in
patching file src/callproc.c
patching file src/editfns.c
patching file src/filelock.c
patching file src/keyboard.c

build.shからの流用

次はconfigureのオプションを頂きます。先程のbuild.shをsourceで取り込みます。

[~/src/emacs/emacs-26.0.91]$ source /path/to/file/build.sh
[~/src/emacs/emacs-26.0.91]$ echo $TERMUX_PKG_EXTRA_CONFIGURE_ARGS
--without-x --with-xpm=no --with-jpeg=no --with-png=no --with-gif=no --with-tiff=no --without-gconf --without-gsettings --with-gnutls --with-xml2 emacs_cv_sanitize_address=yes emacs_cv_prog_cc_nopie=no ac_cv_lib_elf_elf_begin=no gl_cv_func_dup2_works=no

このスクリプトから頂きたいのは、まずTERMUX_PKG_EXTRA_CONFIGURE_ARGSです。ただ、このスクリプトはHOSTでビルドするためのものなのでclangを使わずgccを使う設定になってます。しかしTermux上ではclangを使用するので、そのためのconfigure引数を追加します。

[~/src/emacs/emacs-26.0.91]$ TERMUX_PKG_EXTRA_CONFIGURE_ARGS+=" emacs_cv_prog_cc_no_pie=no"
[~/src/emacs/emacs-26.0.91]$ export TERMUX_PKG_EXTRA_CONFIGURE_ARGS
[~/src/emacs/emacs-26.0.91]$ echo $TERMUX_PKG_EXTRA_CONFIGURE_ARGS
--without-x --with-xpm=no --with-jpeg=no --with-png=no --with-gif=no --with-tiff=no --without-gconf --without-gsettings --with-gnutls --with-xml2 emacs_cv_sanitize_address=yes emacs_cv_prog_cc_nopie=no ac_cv_lib_elf_elf_begin=no gl_cv_func_dup2_works=no emacs_cv_prog_cc_no_pie=no

あと必要なのはexport CANNOT_DUMP=yesです。これは端末に貼り付け適用します。

[~/src/emacs/emacs-26.0.91]$ export CANNOT_DUMP=yes
[~/src/emacs/emacs-26.0.91]$ echo $CANNOT_DUMP
yes

さらにマニュアルにしたがいTermux版Autoconfのファイルをソースツリーにコピーします。

[~/src/emacs/emacs-26.0.91]$ find . -name 'config.sub' -exec chmod u+w '{}' \; -exec cp -f "${PREFIX}/share/libtool/build-aux/config.sub" '{}' \;
[~/src/emacs/emacs-26.0.91]$ find . -name 'config.guess' -exec chmod u+w '{}' \; -exec cp -f "${PREFIX}/share/libtool/build-aux/config.guess" '{}' \;

configure

開発版ソースにはconfigureスクリプト、その他必要なファイルがありません。以下のコマンドで作成します。

[~/src/emacs/emacs-26.0.91]$ autoreconf -ivf
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force
autoreconf: configure.ac: tracing
autoreconf: configure.ac: not using Libtool
autoreconf: running: /data/data/com.termux/files/usr/bin/autoconf --force
autoreconf: running: /data/data/com.termux/files/usr/bin/autoheader --force
autoreconf: configure.ac: not using Automake
autoreconf: Leaving directory `.'

終わったらconfigureします。

ちなみにEmacs26の売りの1つはEmacs版mailutilsではなくGNU mailutilsがデフォルトになったことなんですが、GNU mailutilsはTermuxでパッケージ提供されておらず、ビルドも大変でした。しかもビルドは通ったものの恐らく正常に動かない(少なくとも/etc/passwd絡みの部分は直す必要がある)ので、無視します。わたしは新機能の行番号が見たいんです。

[~/src/emacs/emacs-26.0.91]$ ./configure --prefix="${HOME}" CC=clang CXX=clang++ ${TERMUX_PKG_EXTRA_CONFIGURE_ARGS} --without-pop --without-lcms2
checking for xcrun... no
checking for GNU Make... make
checking build system type... aarch64-unknown-linux-gnu
checking host system type... aarch64-unknown-linux-gnu
Aborted
checking whether the C compiler works... yes
.....

なお、デバッグ機能を有効にするためCFLAGSCFLAGS='-O0 -g3' ./configure --enable-checking='yes,glyphs' --enable-check-lisp-object-type等を指定したい人は、まずCFLAGSを指定しないでmakeして、elispファイルのコンパイルを終わらせてから、改めてCFLAGSを指定してconfigureとmakeをやり直したほうが俄然早いです。デバッグ用のemacsではelispコンパイルステップにとんでもなく時間がかかりました。

make & install

makeします。

[~/src/emacs/emacs-26.0.91]$ make -j4
make -C lib all
make info-real info-dir
make[1]: Entering directory '/data/data/com.termux/files/home/src/emacs/emacs-26.0.91/lib'
  GEN      alloca.h
make[1]: Entering directory '/data/data/com.termux/files/home/src/emacs/emacs-26.0.91'
make -C doc/lispref info
  GEN      dirent.h
make[2]: Entering directory '/data/data/com.termux/files/home/src/emacs/emacs-26.0.91/doc/lispref'
.....

makeが通ったらインストールします。

[~/src/emacs/emacs-26.0.91]$ make install
make -C lib all
make[1]: Entering directory '/data/data/com.termux/files/home/src/emacs/emacs-26.0.91/lib'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/data/data/com.termux/files/home/src/emacs/emacs-26.0.91/lib'
make -C lib-src all
.....

あと、TermuxでEmacsを便利に使用するためにパッケージ版のEmacsにはsite-lisp.elというファイルが含まれてるので、同じものを$HOME/share/emacs/25.3/lisp/emacs-lisp/site-init.elに作成しておけば画面のタップやピンチイン/アウトでコンソールマウスと同等なことが行えるので、作成しておくと便利でしょう。

site-init.el
; Enable terminal mouse events:
(xterm-mouse-mode 1)
(global-set-key [mouse-4] 'scroll-down-line)
(global-set-key [mouse-5] 'scroll-up-line)

インストールしたので実行してみます。以下は前からあるglobal-hl-line-modeと、新機能のdisplay-line-numbers-modeを実行した画面です。

Screenshot_20180212-151647.png

結び

わたしはTermux公式リポジトリにない俺ビルドのアプリを何個か使ってますが、やはり不具合調査用にデバッグオプションでビルドしておかないと、おっかないです。今回も常用アプリなので速度も大切なんですけど、デバッグオプション指定でビルドしました。これでしばらく使ってみます。おわり

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1