顯示具有 compile 標籤的文章。 顯示所有文章
顯示具有 compile 標籤的文章。 顯示所有文章

2023年1月31日 星期二

[Linux] cross compile tmux for Synology DS723+ via DSM 7.1 ToolChain - AMD x86 Linux 4.4.180 (r1000)

終於想不開把家裡的 NAS 升級了,一口氣跳到 AMD Ryzen R1600 型號,接著又要找一下編譯 tmux 的方法 Orz 參考六七年前寫的這篇:[Linux] cross compile tmux for Synology DS216play via DSM 6.1 Tool Chains - STMicroelectronics Monaco Linux 3.10.102 @ Ubuntu 16.04 64bit

過程:
原本找了一台小機器 Ubuntu 18.04 編譯,結果一直出錯,最後還是找個乾淨的機器,一下就搞定。這次用 libevent-2.1.12-stable 時,先略過 openssl 編譯 ,雖然編 openssl 也沒那麼難,但就是這麼懶 XD

Docker 流水帳:

% docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
10175de2f0c4: Pull complete 
Digest: sha256:9dc05cf19a5745c33b9327dba850480dae80310972dea9b05052162e7c7f2763
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
% docker run -it --platform linux/amd64 -p 10022:22 -p 18000:8000 ubuntu:22.04  
# apt update && apt upgrade -y && apt install -y lsb-release net-tools
# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.1 LTS
Release: 22.04
Codename: jammy

# apt install -y gcc g++ make python3 tmux vim git wget xz-utils file

開工:

# cd ~/
# wget https://global.download.synology.com/download/ToolChain/toolchain/7.1-42661/AMD%20x86%20Linux%204.4.180%20%28r1000%29/r1000-gcc850_glibc226_x86_64-GPL.txz
# tar -xvf r1000-gcc850_glibc226_x86_64-GPL.txz

# cd ~/
# wget https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.4.tar.gz
# tar -xvf ncurses-6.4.tar.gz
# cd ncurses-6.4
~/ncurses-6.4# PATH=$HOME/x86_64-pc-linux-gnu/bin:$PATH CC=x86_64-pc-linux-gnu-gcc CFLAGS="-I$HOME/x86_64-pc-lix-gnu/include" ./configure --build x86_64-pc-linux-gnu --prefix=$HOME/x86_64-pc-linux-gnu/
~/ncurses-6.4# PATH=$HOME/x86_64-pc-linux-gnu/bin:$PATH make -j2 install

# cd ~/
# wget https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz
# tar -xvf libevent-2.1.12-stable.tar.gz
# cd libevent-2.1.12-stable
~/libevent-2.1.12-stable# PATH=$HOME/x86_64-pc-linux-gnu/bin:$PATH CC=x86_64-pc-linux-gnu-gcc CFLAGS="-I$HOME/x86_64-pc-lix-gnu/include" ./configure --build x86_64-pc-linux-gnu --prefix=$HOME/x86_64-pc-linux-gnu/ --disable-openssl
~/libevent-2.1.12-stable# PATH=$HOME/x86_64-pc-linux-gnu/bin:$PATH make -j2 install

# cd ~/
# wget https://github.com/tmux/tmux/releases/download/3.3a/tmux-3.3a.tar.gz
# tar -xvf tmux-3.3a.tar.gz 
# cd tmux-3.3a
~/tmux-3.3a# PATH=$HOME/x86_64-pc-linux-gnu/bin:$PATH CC=x86_64-pc-linux-gnu-gcc CFLAGS="-I$HOME/x86_64-pc-linux-gnu/include -I$HOME/x86_64-pc-linux-gnu/include/ncurses" LDFLAGS="-L$HOME/x86_64-pc-linux-gnu/lib" ./configure --build x86_64-pc-linux-gnu --prefix=$HOME/x86_64-pc-linux-gnu/ --enable-static
~/tmux-3.3a# PATH=$HOME/x86_64-pc-linux-gnu/bin:$PATH make -j2
...
x86_64-pc-linux-gnu-gcc -std=gnu99 -O2    -I/root/x86_64-pc-linux-gnu/include -I/root/x86_64-pc-linux-gnu/include/ncurses -static  -L/root/x86_64-pc-linux-gnu/lib -o tmux alerts.o arguments.o attributes.o cfg.o client.o cmd-attach-session.o cmd-bind-key.o cmd-break-pane.o cmd-capture-pane.o cmd-choose-tree.o cmd-command-prompt.o cmd-confirm-before.o cmd-copy-mode.o cmd-detach-client.o cmd-display-menu.o cmd-display-message.o cmd-display-panes.o cmd-find-window.o cmd-find.o cmd-if-shell.o cmd-join-pane.o cmd-kill-pane.o cmd-kill-server.o cmd-kill-session.o cmd-kill-window.o cmd-list-buffers.o cmd-list-clients.o cmd-list-keys.o cmd-list-panes.o cmd-list-sessions.o cmd-list-windows.o cmd-load-buffer.o cmd-lock-server.o cmd-move-window.o cmd-new-session.o cmd-new-window.o cmd-parse.o cmd-paste-buffer.o cmd-pipe-pane.o cmd-queue.o cmd-refresh-client.o cmd-rename-session.o cmd-rename-window.o cmd-resize-pane.o cmd-resize-window.o cmd-respawn-pane.o cmd-respawn-window.o cmd-rotate-window.o cmd-run-shell.o cmd-save-buffer.o cmd-select-layout.o cmd-select-pane.o cmd-select-window.o cmd-send-keys.o cmd-server-access.o cmd-set-buffer.o cmd-set-environment.o cmd-set-option.o cmd-show-environment.o cmd-show-messages.o cmd-show-options.o cmd-show-prompt-history.o cmd-source-file.o cmd-split-window.o cmd-swap-pane.o cmd-swap-window.o cmd-switch-client.o cmd-unbind-key.o cmd-wait-for.o cmd.o colour.o control-notify.o control.o environ.o file.o format.o format-draw.o grid-reader.o grid-view.o grid.o input-keys.o input.o job.o key-bindings.o key-string.o layout-custom.o layout-set.o layout.o log.o menu.o mode-tree.o names.o notify.o options-table.o options.o paste.o popup.o proc.o regsub.o resize.o screen-redraw.o screen-write.o screen.o server-acl.o server-client.o server-fn.o server.o session.o spawn.o status.o style.o tmux.o tty-acs.o tty-features.o tty-keys.o tty-term.o tty.o utf8.o window-buffer.o window-client.o window-clock.o window-copy.o window-customize.o window-tree.o window.o xmalloc.o osdep-linux.o    compat/closefrom.o compat/fgetln.o compat/freezero.o compat/getdtablecount.o compat/getpeereid.o compat/getprogname.o compat/setproctitle.o compat/strlcat.o compat/strlcpy.o compat/strtonum.o compat/recallocarray.o compat/getopt.o compat/imsg.o compat/imsg-buffer.o compat/vis.o compat/unvis.o compat/fdforkpty.o -lutil -lncurses -levent_core -lm  -lncurses -lresolv
cmd-parse.o: In function `yylex_token_tilde':
cmd-parse.c:(.text+0x61d): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
cmd-parse.c:(.text+0x6a9): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/root/x86_64-pc-linux-gnu/lib/libevent_core.a(evutil.o): In function `test_for_getaddrinfo_hacks':
evutil.c:(.text+0x1836): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/root/x86_64-pc-linux-gnu/lib/libevent_core.a(evutil.o): In function `evutil_unparse_protoname':
evutil.c:(.text+0x1272): warning: Using 'getprotobynumber' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/root/x86_64-pc-linux-gnu/lib/libevent_core.a(evutil.o): In function `evutil_parse_servname':
evutil.c:(.text+0x11ee): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

~/tmux-3.3a# file tmux
tmux: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, with debug_info, not stripped

~/tmux-3.3a# python3 -m http.server 
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

還記得當初跑 docker 時有把本機的 18000 port 對到裡頭的 8000 port ,這時就可以靠 http://localhost:18000/tmux 去下載 tmux 來用。

實際運行:

$ uname -a
Linux NAS 4.4.180+ #42962 SMP Thu Dec 8 21:34:11 CST 2022 x86_64 GNU/Linux synology_r1000_723+

$ ~/bin/tmux -V
tmux-tool 3.3a

另外,在 NAS 內運行時,可以多設定 shell 環境資訊:

$ cat ~/.profile 
export PATH=$HOME/bin:$PATH
export TERM=xterm

收工!

2017年5月31日 星期三

[Linux] cross compile tmux for Synology DS216play via DSM 6.1 Tool Chains - STMicroelectronics Monaco Linux 3.10.102 @ Ubuntu 16.04 64bit

連假最後一天跑來把玩一下 cross compiler ,想說未來應該會越來越常用 NAS 做事,覺得裡頭沒有個 tmux/screen 很煩,然而,等了很久還是沒人為 DS216play 編譯 tmux ,一直很搞不懂,直到我翻了這張表出來:

https://www.synology.com/en-global/knowledgebase/DSM/tutorial/General/What_kind_of_CPU_does_my_NAS_have

System Model CPU Model Cores Threads FPU Package Arch RAM
DS216play STM STiH412 Dual Core 2 Yes Monaco DDR3 1 GB

好的,看起來有點冷門的 STM STiH412/Monaco 囧,不過找一些討論串才知道,由於要讓 DS216play 可以做一些多媒體影音的事,所以,就別抱怨了 XD

下載 Tool chains: https://sourceforge.net/projects/dsgpl/files/DSM%206.1%20Tool%20Chains/STMicroelectronics%20Monaco%20Linux%203.10.102/

$ wget https://sourceforge.net/projects/dsgpl/files/DSM%206.1%20Tool%20Chains/STMicroelectronics%20Monaco%20Linux%203.10.102/monaco-gcc493_glibc220_hard-GPL.txz/download -O monaco-gcc493_glibc220_hard-GPL.txz
$ tar -xvf monaco-gcc493_glibc220_hard-GPL.txz
$ tree -L 1 arm-unknown-linux-gnueabi/
arm-unknown-linux-gnueabi/
├── arm-unknown-linux-gnueabi
├── bin
├── build.log.bz2
├── include
├── lib
├── libexec
└── share


前置環境:

$ sudo apt install make python gcc
$ chmod 755 $HOME/arm-unknown-linux-gnueabi $HOME/arm-unknown-linux-gnueabi/include $HOME/arm-unknown-linux-gnueabi/lib $HOME/arm-unknown-linux-gnueabi/bin $HOME/arm-unknown-linux-gnueabi/share


編譯 ncurses:

$ wget ftp://invisible-island.net/ncurses/ncurses.tar.gz
$ tar -xvf ncurses.tar.gz
$ cd ncurses-5.9
$ PATH=$PATH:$HOME/arm-unknown-linux-gnueabi/bin CC=$HOME/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-gcc CFLAGS="-I$HOME/arm-unknown-linux-gnueabi/include"  ./configure --host arm-unknown-linux-gnueabi --prefix=$HOME/arm-unknown-linux-gnueabi
$ PATH=$PATH:$HOME/arm-unknown-linux-gnueabi/bin make
$ PATH=$PATH:$HOME/arm-unknown-linux-gnueabi/bin make install


編譯 libevent:

$ wget https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz
$ tar -xvf libevent-2.1.8-stable.tar.gz
$ cd libevent-2.1.8-stable
$ PATH=$PATH:$HOME/arm-unknown-linux-gnueabi/bin CC=$HOME/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-gcc CFLAGS="-I$HOME/arm-unknown-linux-gnueabi/include"  ./configure --host arm-unknown-linux-gnueabi --prefix=$HOME/arm-unknown-linux-gnueabi
$ PATH=$PATH:$HOME/arm-unknown-linux-gnueabi/bin CC=$HOME/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-gcc CFLAGS="-I$HOME/arm-unknown-linux-gnueabi/include"  make
$ PATH=$PATH:$HOME/arm-unknown-linux-gnueabi/bin make install


編譯 tmux:

$ wget https://github.com/tmux/tmux/releases/download/2.5/tmux-2.5.tar.gz
$ tar -xvf tmux-2.5.tar.gz
$ cd tmux-2.5
$ PATH=$PATH:$HOME/arm-unknown-linux-gnueabi/bin CC=$HOME/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-gcc CFLAGS="-I$HOME/arm-unknown-linux-gnueabi/include -I$HOME/arm-unknown-linux-gnueabi/include/ncurses" LDFLAGS="-L$HOME/arm-unknown-linux-gnueabi/lib" ./configure --host arm-unknown-linux-gnueabi --prefix=$HOME/arm-unknown-linux-gnueabi
$ PATH=$PATH:$HOME/arm-unknown-linux-gnueabi/bin make
$ file tmux
tmux: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, not stripped


or:

$ PATH=$PATH:$HOME/arm-unknown-linux-gnueabi/bin CC=$HOME/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-gcc CFLAGS="-I$HOME/arm-unknown-linux-gnueabi/include -I$HOME/arm-unknown-linux-gnueabi/include/ncurses" LDFLAGS="-L$HOME/arm-unknown-linux-gnueabi/lib" ./configure --host arm-unknown-linux-gnueabi --prefix=$HOME/arm-unknown-linux-gnueabi --enable-static
$ PATH=$PATH:$HOME/arm-unknown-linux-gnueabi/bin make
...
...
cmd-string.o: In function `cmd_string_split':
cmd-string.c:(.text+0x820): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
cmd-string.c:(.text+0x760): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$HOME/arm-unknown-linux-gnueabi/lib/libevent.a(evutil.o): In function `test_for_getaddrinfo_hacks':
evutil.c:(.text+0x1be8): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$HOME/arm-unknown-linux-gnueabi/lib/libevent.a(evutil.o): In function `evutil_unparse_protoname':
evutil.c:(.text+0x1554): warning: Using 'getprotobynumber' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$HOME/arm-unknown-linux-gnueabi/lib/libevent.a(evutil.o): In function `evutil_parse_servname':
evutil.c:(.text+0x14a0): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ file tmux
tmux: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, not stripped


收工

2016年2月27日 星期六

Android 開發筆記 - 在 Android Studio 環境上,使用 Google Analytics SDK / Admob SDK

使用 Android Studio 1.5.1 版,原先參考 Google 官方文件,結果一直爆問題 :P 其中 Google Analytics SDK 跟 Admob SDK 都會需要 Google Service 的環境,而碰到 Google Service 的引入不斷出錯,以下單純記錄修正流程。

參考 https://developers.google.com/analytics/devguides/collection/android/v4/https://developers.google.com/admob/android/app 資訊,更新 AndroidManifest.xml 位置,添加:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>


接著在 build.gradle (Project) 添加:

classpath 'com.google.gms:google-services:2.0.0-alpha6'

在 build.gradle (app) 添加:

dependencies {
//...
compile 'com.google.android.gms:play-services-analytics:8.4.0'
}
apply plugin: 'com.google.gms.google-services'


結果一直出錯:Gradle sync failed: Unable to load class 'com.android.sdklib.repository.FullRevision'. 這種很 general 的訊息。

甚至跑去看看 googlesample 檔案,如:
分別查看:build.gradleapp/build.gradle 和 gradle/wrapper/gradle-wrapper.properties 三個檔案。

改採用:

dependencies {
        //classpath 'com.android.tools.build:gradle:1.5.0'
        classpath 'com.android.tools.build:gradle-experimental:0.4.0'

        classpath 'com.android.tools.build:gradle:2.0.0-beta5'
        classpath 'com.google.gms:google-services:2.0.0-beta5'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
}


仍是一樣的現象,最後靠直覺,嘗試亂改 classpath 'com.google.gms:google-services:1.0.0+' 後,會看到錯誤訊息引導說,可以查看 metadata 得知有哪些版本可用:

https://jcenter.bintray.com/com/google/gms/google-services/maven-metadata.xml

就這樣,直接挑沒有 beta/alpha 字眼:

dependencies {
        classpath 'com.android.tools.build:gradle:1.5.0'
        classpath 'com.android.tools.build:gradle-experimental:0.4.0'
        classpath 'com.google.gms:google-services:1.5.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
}


以及 gradle/wrapper/gradle-wrapper.properties 使用:

#distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-all.zip

如此一來,終於解掉編譯問題。接續就可以參考 Google Analytics SDK/Admob SDK 的文件,例如產生 google-services.json 以及 AnalyticsApplication extends Application 等用法等。

最後,我自己的用法:

AndroidManifest.xml:
...
<application
        android:name=".MyApplication"
        ...
>
...
</application>


MyApplication.java:
import android.app.Application;
import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.Tracker;
public class MyApplication extends Application {
        private Tracker mTracker;
        synchronized public Tracker getDefaultTracker() {
               if (mTracker == null) {
                      GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
                      // To enable debug logging use: adb shell setprop log.tag.GAv4 DEBUG
                      //mTracker = analytics.newTracker(R.xml.global_tracker);
                      mTracker = analytics.newTracker("UA-XXXXXXX-XX");
               }
               return mTracker;
        }
}


build.gradle (app):
dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.12'

        compile 'com.android.support:appcompat-v7:23.2.0'
        compile 'com.android.support:design:23.2.0'

        // Google Analytics & Admob
        compile 'com.google.android.gms:play-services:8.4.0'
        compile 'com.google.android.gms:play-services-ads:8.4.0'
        compile 'com.google.android.gms:play-services-analytics:8.4.0'
}


build.gradle (Project):
dependencies {
        classpath 'com.android.tools.build:gradle:1.5.0'
        classpath 'com.android.tools.build:gradle-experimental:0.4.0'

        classpath 'com.google.gms:google-services:1.5.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
}


MainActivity.java:
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        MyApplication application = (MyApplication) getApplication();
        Tracker mTracker = application.getDefaultTracker();
        mTracker.setScreenName("main");
        mTracker.send(new HitBuilders.ScreenViewBuilder().build());
        //...
}

2014年7月3日 星期四

iOS 開發筆記 - 使用 C++ Source Code

最近把玩練習時,想說用一下 CPP 的,寫完後發現要整進 Xcode 卻發現 compile error,例如在 AppDelete.m 中:

#include "Test.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
 
    Test *obj = new Test();
 
    return YES;
}


其中 Test.h:

#ifndef __Test__Test__
#define __Test__Test__

#include <iostream>

class Test {
public:
    int x;
};


#endif /* defined(__Test__Test__) */


編譯時就會顯示找不到 iostream 等訊息,解法?早期大概有指定 Compile 參數,現在還滿容易的,只要把用到 CPP 的 Objective-C 檔案,從 .m 改成 .mm 即可。

以此就是將 AppDelete.m 更名為 AppDelete.mm ,就可以編譯成功,真是太方便了!