├── .github └── FUNDING.yml ├── .gitignore ├── .travis.yml ├── CB-Template ├── Android.mk ├── AndroidNdkTemplate.cbp ├── Application.mk ├── Makefile ├── autoinstall │ ├── autoinstall.ico │ ├── autoinstall.iss │ ├── autoinstall.rtf │ ├── autoinstall_0.bmp │ ├── autoinstall_1.bmp │ └── src │ │ ├── CodeBlocks.config │ │ └── templates │ │ │ └── wizard │ │ │ └── config.script │ │ └── CodeBlocks │ │ └── templates │ │ └── wizard │ │ └── ndk_android │ │ ├── exec │ │ ├── android-elf-cleaner32.exe │ │ └── cbp2ndk32.exe │ │ ├── files │ │ ├── Makefile │ │ └── main.cpp │ │ ├── logo.png │ │ ├── wizard.png │ │ └── wizard.script ├── hdk-main.h ├── ndk-main.c └── ndk-test.cpp ├── CBTemplate.workspace ├── LICENSE ├── README.md ├── android-elf-cleaner ├── android-elf-cleaner.cbp ├── android-elf-cleaner.cpp ├── elf.h └── mio.hpp ├── cbp2ndk ├── README.md ├── cbp2ndk.cbp ├── dist │ ├── CMakeLists.txt │ └── Test.cbp ├── src │ ├── cbp2ndk-CbConf.cpp │ ├── cbp2ndk-CbConf.h │ ├── cbp2ndk-cppflags.h │ ├── cbp2ndk-dump.cpp │ ├── cbp2ndk-parse.cpp │ ├── cbp2ndk-write.cpp │ ├── cbp2ndk.cpp │ ├── cbp2ndk.h │ ├── cbp2ndk.rc │ └── extern │ │ ├── argh.h │ │ ├── tinyxml2.cpp │ │ ├── tinyxml2.h │ │ ├── tixml2cx.h │ │ └── tixml2ex.h └── version.h └── docs ├── ADBANDROIDVIEWER.EN.md ├── ADBANDROIDVIEWER.RU.md ├── CBNDKAUTOINSTALL.EN.md ├── CBNDKAUTOINSTALL.RU.md ├── CBP2NDK.EN.md ├── CBP2NDK.RU.md ├── CodeBlocksNdkTemplate.exe ├── README.EN.md ├── README.RU.md ├── README.md ├── _config.yml ├── android-elf-cleaner.zip ├── cbp2ndk.zip └── img ├── Image1.png ├── Image10.png ├── Image11.png ├── Image12.png ├── Image13.png ├── Image14.png ├── Image15.png ├── Image2.png ├── Image3.png ├── Image4.png ├── Image5.png ├── Image6.png ├── Image7.png ├── Image8.png ├── Image9.png ├── Wizard1.png ├── Wizard2.png ├── Wizard3.png ├── Wizard4.png ├── Wizard5.png ├── Wizard6.png ├── Wizard7.png ├── adbviewer-1-en.png ├── adbviewer-1-ru.png ├── adbviewer-2-terminal-en.png ├── adbviewer-script-record.gif ├── adbviewer-script-run.gif ├── adbviewer-terminal.gif └── banner.png /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with a single custom sponsorship URL 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .svn 3 | *.save 4 | *.layout 5 | *.bmarks 6 | *.depend 7 | *.sh 8 | /bin 9 | /obj 10 | *.sh 11 | 12 | # Prerequisites 13 | *.d 14 | 15 | # Object files 16 | *.o 17 | *.ko 18 | *.obj 19 | *.elf 20 | 21 | # Linker output 22 | *.ilk 23 | *.map 24 | *.exp 25 | 26 | # Precompiled Headers 27 | *.gch 28 | *.pch 29 | 30 | # Libraries 31 | *.lib 32 | *.a 33 | *.la 34 | *.lo 35 | 36 | # Shared objects (inc. Windows DLLs) 37 | *.dll 38 | *.so 39 | *.so.* 40 | *.dylib 41 | 42 | # Executables 43 | *.out 44 | *.app 45 | *.i*86 46 | *.x86_64 47 | *.hex 48 | 49 | # Debug files 50 | *.dSYM/ 51 | *.su 52 | *.idb 53 | *.pdb 54 | 55 | # Kernel Module Compile Results 56 | *.mod* 57 | *.cmd 58 | .tmp_versions/ 59 | modules.order 60 | Module.symvers 61 | Mkfile.old 62 | dkms.conf 63 | /cbp2ndk/bin/Debug 64 | /cbp2ndk/bin/Release 65 | /cbp2ndk/obj/Debug/src 66 | /cbp2ndk/obj/Release/src 67 | /docs/img/pspbrwse.jbf 68 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | sudo: reguired 3 | os: 4 | - windows 5 | compiler: 6 | - gcc 7 | script: 8 | - dir 9 | - cd cbp2ndk/dist 10 | - mkdir -p test 11 | - cd test 12 | - cmake -G"MinGW Makefiles" .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin" 13 | - cmake --build . --config "Debug" 14 | - dir 15 | before_deploy: 16 | - tar -zcf ${TRAVIS_BUILD_DIR}${REPO}-cbp2ndk-${TRAVIS_BUILD_NUMBER}.tar.gz cbp2ndk.exe 17 | deploy: 18 | provider: releases 19 | skip_cleanup: true 20 | api_key: $GH_TOKEN 21 | file_glob: true 22 | file: ${TRAVIS_BUILD_DIR}${REPO}-cbp2ndk-${TRAVIS_BUILD_NUMBER}.tar.gz 23 | on: 24 | all_branches: true 25 | tags: false 26 | -------------------------------------------------------------------------------- /CB-Template/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | include $(CLEAR_VARS) 3 | LOCAL_MODULE := hello_world 4 | LOCAL_CPP_EXTENSION := .cpp 5 | LOCAL_SRC_FILES := ndk-main.c ndk-test.cpp 6 | LOCAL_CFLAGS := -Wall 7 | LOCAL_LDLIBS := -llog 8 | LOCAL_C_INCLUDES := ./ 9 | include $(BUILD_EXECUTABLE) 10 | -------------------------------------------------------------------------------- /CB-Template/AndroidNdkTemplate.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 44 | 45 | -------------------------------------------------------------------------------- /CB-Template/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := armeabi-v7a 2 | APP_STL := c++_static 3 | # c++_shared 4 | # APP_OPTIM := debug 5 | APP_PLATFORM := android-22 6 | APP_BUILD_SCRIPT := Android.mk 7 | -------------------------------------------------------------------------------- /CB-Template/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Code::Blocks + Android NDK project template 5 | # Copyright (c) 2016-2019 PS 6 | # HOWTO: https://clnviewer.github.io/Code-Blocks-Android-NDK/ 7 | # 8 | # - No root device! 9 | # - Build Debug (NDK toolchain) 10 | # - Build Release (NDK toolchain) 11 | # - Run from device 12 | # - Debug from device. 13 | # - Auto start/stop gdbserverfrom device. 14 | # - No wrappers from Gradle/Java code required, works directly with the device. 15 | # - Advanced project export to Android.mk file format, possible using utility cbp2ndk. 16 | # 17 | # Permission is hereby granted, free of charge, to any person obtaining a copy 18 | # of this software and associated documentation files (the "Software"), to deal 19 | # in the Software without restriction, including without limitation the rights 20 | # to use, copy, modify, merge, publish, distribute, sub license, and/or sell 21 | # copies of the Software, and to permit persons to whom the Software is 22 | # furnished to do so, subject to the following conditions: 23 | # 24 | # The above copyright notice and this permission notice shall be included in all 25 | # copies or substantial portions of the Software. 26 | # 27 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 30 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 | # SOFTWARE. 34 | 35 | PLATFORM := armeabi-v7a 36 | NDKROOT := C:\__BuildSource\__LIB__\android-ndk-r20-beta2 37 | PROJECT := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) 38 | BUILDTAG := $(filter-out $@,$(MAKECMDGOALS)) 39 | BUILDOPT := 40 | 41 | include Application.mk 42 | include $(APP_BUILD_SCRIPT) 43 | 44 | ifeq ($(OS),Windows_NT) 45 | CONFCBP := $(shell dir *.cbp | findstr .cbp) 46 | else 47 | CONFCBP := $(shell find $("./") -name '*.cbp') 48 | endif 49 | 50 | ifneq ($(APP_ABI),all) 51 | PLATFORM = $(APP_ABI) 52 | endif 53 | 54 | ifneq ($(ANALIZE),) 55 | BUILDOPT += NDK_ANALIZE=1 56 | endif 57 | 58 | ifeq ($(BUILDTAG),Debug) 59 | BUILDOPT += V=1 NDK_DEBUG=1 60 | else 61 | BUILDOPT += -j 4 62 | endif 63 | 64 | all: allndk 65 | Debug: allndk adbsetup adbdebug buildscript rundebug 66 | Release: allndk adbsetup adbexec buildscript 67 | cleanDebug: clean 68 | cleanRelease: clean 69 | cleanall: clean 70 | 71 | allndk: 72 | @echo '==== Build $(BUILDTAG) -> $(APP_ABI) platform -> active device: [ $(PLATFORM) ] ====' 73 | @cbp2ndk.exe $(BUILDTAG) $(CONFCBP) 74 | @Cmd.exe /C $(NDKROOT)\ndk-build.cmd NDK_APPLICATION_MK=$(PROJECT)Application.mk NDK_PROJECT_PATH=$(PROJECT) $(BUILDOPT) 75 | 76 | clean: 77 | @echo '==== Clean ====' 78 | @Cmd.exe /C $(NDKROOT)\ndk-build.cmd NDK_APPLICATION_MK=$(PROJECT)Application.mk NDK_PROJECT_PATH=$(PROJECT) clean 79 | @Cmd.exe /C adb.exe shell rm -f /data/local/tmp/$(LOCAL_MODULE) 80 | 81 | adbsetup: 82 | @echo '==== ADB SETUP: [ $(PLATFORM) ] ====' 83 | @Cmd.exe /C android-elf-cleaner.exe $(PROJECT)libs\$(PLATFORM)\$(LOCAL_MODULE) 84 | @Cmd.exe /C adb.exe push $(PROJECT)libs\$(PLATFORM)\$(LOCAL_MODULE) /data/local/tmp/$(LOCAL_MODULE) 85 | @Cmd.exe /C adb.exe shell /system/bin/chmod 0777 /data/local/tmp/$(LOCAL_MODULE) 86 | 87 | adbexec: 88 | @echo '==== ADB RUN: [ $(PLATFORM) ] ====' 89 | @Cmd.exe /C adb.exe shell /data/local/tmp/$(LOCAL_MODULE) $(CBP2NDK_CMDLINE) 90 | 91 | adbdebug: 92 | @echo '==== GDB Debug: [ $(PLATFORM) ] ====' 93 | @Cmd.exe /C adb.exe push $(PROJECT)libs\$(PLATFORM)\gdb.setup /data/local/tmp/gdb.setup 94 | @Cmd.exe /C adb.exe push $(PROJECT)libs\$(PLATFORM)\gdbserver /data/local/tmp/gdbserver 95 | @Cmd.exe /C adb.exe shell /system/bin/chmod 0777 /data/local/tmp/gdbserver 96 | 97 | rundebug: 98 | @Cmd.exe /C DebugRemote.cmd 99 | 100 | buildscript: 101 | ifeq (,$(wildcard ./RunRemote.cmd)) 102 | @echo "adb.exe shell /data/local/tmp/$(LOCAL_MODULE) $(CBP2NDK_CMDLINE)" >RunRemote.cmd 103 | endif 104 | ifeq (,$(wildcard ./DebugRemote.cmd)) 105 | @echo "adb.exe forward tcp:59999 tcp:59999" >DebugRemote.cmd 106 | @echo "start \"$(PLATFORM) GDB server\" /MIN adb.exe shell /data/local/tmp/gdbserver :59999 /data/local/tmp/$(LOCAL_MODULE) $(CBP2NDK_CMDLINE)" >>DebugRemote.cmd 107 | @echo "exit" >>DebugRemote.cmd 108 | endif 109 | 110 | .PHONY: clean all 111 | 112 | -------------------------------------------------------------------------------- /CB-Template/autoinstall/autoinstall.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Code-Blocks-Android-NDK/bd65ca4424728887d86a6c267de233ae58373f1d/CB-Template/autoinstall/autoinstall.ico -------------------------------------------------------------------------------- /CB-Template/autoinstall/autoinstall.iss: -------------------------------------------------------------------------------- 1 | ; Script generated by the Inno Script Studio Wizard. 2 | #pragma include __INCLUDE__ + ";" + ReadReg(HKLM, "Software\Mitrich Software\Inno Download Plugin", "InstallDir") 3 | 4 | #include "..\..\cbp2ndk\version.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | [Setup] 19 | AppId={{00A125D3-8122-4ECA-8675-715EE4BF1F82} 20 | AppName=CodeBlocksNdkTemplate 21 | AppVersion={#CBP_FULLVERSION_STRING} 22 | AppVerName="Code::Blocks NDK Template {#CBP_FULLVERSION_STRING}" 23 | AppPublisher=PS 24 | AppPublisherURL=https://clnviewer.github.io/Code-Blocks-Android-NDK/ 25 | AppSupportURL=https://clnviewer.github.io/Code-Blocks-Android-NDK/ 26 | AppUpdatesURL=https://clnviewer.github.io/Code-Blocks-Android-NDK/ 27 | ShowLanguageDialog=auto 28 | CreateAppDir=no 29 | WizardSmallImageFile=autoinstall_0.bmp 30 | WizardSmallImageBackColor=clWhite 31 | WizardImageFile=autoinstall_1.bmp 32 | WizardImageBackColor=clWhite 33 | OutputDir=..\..\docs 34 | OutputBaseFilename=CodeBlocksNdkTemplate 35 | SetupIconFile=autoinstall.ico 36 | InfoAfterFile=autoinstall.rtf 37 | Compression=lzma 38 | SolidCompression=yes 39 | 40 | [Languages] 41 | Name: "en"; MessagesFile: "compiler:Default.isl" 42 | Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl" 43 | Name: "zh"; MessagesFile: "compiler:Languages\ChineseSimplified.isl" 44 | Name: "cn"; MessagesFile: "compiler:Languages\ChineseTraditional.isl" 45 | Name: "fi"; MessagesFile: "compiler:Languages\Finnish.isl" 46 | Name: "fr"; MessagesFile: "compiler:Languages\French.isl" 47 | Name: "de"; MessagesFile: "compiler:Languages\German.isl" 48 | Name: "hu"; MessagesFile: "compiler:Languages\Hungarian.isl" 49 | Name: "it"; MessagesFile: "compiler:Languages\Italian.isl" 50 | Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl" 51 | Name: "pt_br"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl" 52 | Name: "es"; MessagesFile: "compiler:Languages\Spanish.isl" 53 | Name: "catalan"; MessagesFile: "compiler:Languages\Catalan.isl" 54 | Name: "corsican"; MessagesFile: "compiler:Languages\Corsican.isl" 55 | Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl" 56 | Name: "danish"; MessagesFile: "compiler:Languages\Danish.isl" 57 | Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl" 58 | Name: "greek"; MessagesFile: "compiler:Languages\Greek.isl" 59 | Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl" 60 | Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl" 61 | Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl" 62 | Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl" 63 | Name: "swedish"; MessagesFile: "compiler:Languages\Swedish.isl" 64 | Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl" 65 | Name: "arabic"; MessagesFile: "compiler:Languages\Arabic.isl" 66 | Name: "korea"; MessagesFile: "compiler:Languages\Korean.isl" 67 | 68 | [CustomMessages] 69 | CbOverwriteDescription = Overwrite C::B template configuration (v.17.12) 70 | ru.CbOverwriteDescription = Перезаписать конфигурацию шаблонов C::B (v.17.12) 71 | AdbViewerDescription = Install ADB Viewer (view and control your Android device from a PC) 72 | ru.AdbViewerDescription = Установить ADB Viewer (просмотр и управления устройством Android с ПК) 73 | 74 | [Tasks] 75 | Name: "installcbconfig"; Description: {cm:CbOverwriteDescription}; Flags: unchecked 76 | Name: "installadbviewer"; Description: {cm:AdbViewerDescription}; Flags: unchecked 77 | 78 | [Files] 79 | Source: "src\CodeBlocks\*"; Check: GetCodeblocksTemplateDestination; DestDir: "{code:TemplateDestination}"; Flags: ignoreversion recursesubdirs createallsubdirs; 80 | Source: "src\CodeBlocks.config\*"; Check: GetCodeblocksTemplateDestination; DestDir: "{code:TemplateDestination}"; Tasks: installcbconfig; Flags: ignoreversion recursesubdirs createallsubdirs; 81 | Source: "{tmp}\AndroidADBViewer.msi"; Check: GetADBAndroidViewer; DestDir: {tmp}; Tasks: installadbviewer; Flags: external deleteafterinstall; 82 | 83 | [Run] 84 | Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\AndroidADBViewer.msi"" /qb"; WorkingDir: {tmp}; Tasks: installadbviewer; 85 | 86 | [Code] 87 | 88 | var cbTemplateDest : String; 89 | 90 | function GetCodeblocksTemplateDestination(): Boolean; 91 | var 92 | len: Integer; 93 | 94 | begin 95 | cbTemplateDest := ''; 96 | 97 | RegQueryStringValue(HKCU, 'SOFTWARE\CodeBlocks', 'Path', cbTemplateDest); 98 | len := Length(cbTemplateDest); 99 | if len = 0 then 100 | begin 101 | RegQueryStringValue(HKU, 'SOFTWARE\CodeBlocks', 'Path', cbTemplateDest); 102 | len := Length(cbTemplateDest); 103 | end; 104 | 105 | if len > 0 then 106 | begin 107 | Insert('/share/CodeBlocks/', cbTemplateDest, len + 1); 108 | end; 109 | Result := len > 0; 110 | end; 111 | 112 | function TemplateDestination(Param: String) : String; 113 | begin 114 | Result := cbTemplateDest; 115 | end; 116 | 117 | function GetADBAndroidViewer(): Boolean; 118 | begin 119 | Result := idpDownloadFile('https://clnviewer.github.io/ADB-Android-Viewer/dist/Android-ADB-Viewer.msi', ExpandConstant('{tmp}\AndroidADBViewer.msi')); 120 | end; 121 | -------------------------------------------------------------------------------- /CB-Template/autoinstall/autoinstall.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1251\deff0\nouicompat\deflang1049{\fonttbl{\f0\fnil\fcharset0 Calibri;}{\f1\fnil\fcharset204 Calibri;}} 2 | {\colortbl ;\red255\green0\blue0;\red0\green77\blue187;\red75\green172\blue198;\red165\green165\blue165;\red0\green176\blue80;\red0\green0\blue255;} 3 | {\*\generator Riched20 10.0.17134}\viewkind4\uc1 4 | \pard\sl276\slmult1\f0\fs20\lang2057 If you didn\rquote t select item -\par 5 | \cf1 "Overwrite C::B template configuration (v.17.12)"\cf0 ,\par 6 | you need to set the te\lang1033 m\lang2057 plate yourself in configuration \cf2\b\fs18 Code::Blocks\cf0\b0\fs20 :\par 7 | \par 8 | Open file \lang1033 from path:\f1\fs22\lang1049\par 9 | \cf2\f0\fs18\lang2057 <\b Code::Blocks base directory\b0 >\par 10 | \\share\\CodeBlocks\\templates\\wizard\\config.script\cf0\fs22\par 11 | \fs20\par 12 | Add to function \cf3\b\fs22 RegisterWizards()\cf2 \cf0\b0\fs20 this code:\fs22\par 13 | 14 | \pard\sl240\slmult1\par 15 | \fs20 \cf3 function \b RegisterWizards\b0 ()\cf0\par 16 | \{\par 17 | \cf4 //...\par 18 | \cf0 \cf3\b RegisterWizard\cf0\b0 (\par 19 | wizProject,\par 20 | _T(\cf5 "ndk_android"\cf0 ),\par 21 | _T(\cf5 "NDK Android"\cf0 ),\par 22 | _T(\cf5 "Native"\cf0 )\par 23 | 24 | \pard\ri1488\sl240\slmult1 );\par 25 | 26 | \pard\sl240\slmult1 \cf4 //...\par 27 | 28 | \pard\sl276\slmult1\cf0\fs22\par 29 | \fs20 Run \cf2\b\fs22 C::B\b0\fs20 \cf0 an select new project from \cf2\b\fs22 NDK Android\cf0\b0 \fs20 template.\par 30 | Github: {{\field{\*\fldinst{HYPERLINK https://clnviewer.github.io/Code-Blocks-Android-NDK/ }}{\fldrslt{https://clnviewer.github.io/Code-Blocks-Android-NDK/\ul0\cf0}}}}\f0\fs20\par 31 | \f1\fs22\lang1049\par 32 | 33 | \pard\sl240\slmult1\f0\fs20\lang2057\par 34 | } 35 | -------------------------------------------------------------------------------- /CB-Template/autoinstall/autoinstall_0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Code-Blocks-Android-NDK/bd65ca4424728887d86a6c267de233ae58373f1d/CB-Template/autoinstall/autoinstall_0.bmp -------------------------------------------------------------------------------- /CB-Template/autoinstall/autoinstall_1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Code-Blocks-Android-NDK/bd65ca4424728887d86a6c267de233ae58373f1d/CB-Template/autoinstall/autoinstall_1.bmp -------------------------------------------------------------------------------- /CB-Template/autoinstall/src/CodeBlocks.config/templates/wizard/config.script: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3 3 | * http://www.gnu.org/licenses/gpl-3.0.html 4 | * 5 | * $Revision: 10722 $ 6 | * $Id: config.script 10722 2016-01-28 14:39:15Z mortenmacfly $ 7 | * $HeadURL: svn+ssh://killerbot@svn.code.sf.net/p/codeblocks/code/branches/release-17.xx/src/plugins/scriptedwizard/resources/config.script $ 8 | */ 9 | 10 | // 11 | // Main wizards configuration script. 12 | // Here, we register all the available wizards. 13 | // 14 | 15 | function RegisterWizards() 16 | { 17 | // 18 | // project wizards 19 | // 20 | RegisterWizard(wizProject, _T("empty"), _T("Empty project"), _T("Console")); 21 | RegisterWizard(wizProject, _T("fortran/app"), _T("Fortran application"), _T("Fortran")); 22 | RegisterWizard(wizProject, _T("fortran/lib"), _T("Fortran library"), _T("Fortran")); 23 | RegisterWizard(wizProject, _T("fortran/dll"), _T("Fortran DLL"), _T("Fortran")); 24 | RegisterWizard(wizProject, _T("console"), _T("Console application"), _T("Console")); 25 | RegisterWizard(wizProject, _T("d"), _T("D application"), _T("D language")); 26 | if (PLATFORM == PLATFORM_MSW) 27 | { 28 | RegisterWizard(wizProject, _T("directx"), _T("Direct/X project"), _T("2D/3D Graphics")); 29 | RegisterWizard(wizProject, _T("dll"), _T("Dynamic Link Library"), _T("Console")); 30 | RegisterWizard(wizProject, _T("sys"), _T("Kernel Mode Driver"), _T("Native")); 31 | } 32 | RegisterWizard(wizProject, _T("ndk_android"), _T("NDK Android"), _T("Native")); 33 | RegisterWizard(wizProject, _T("fltk"), _T("FLTK project"), _T("GUI")); 34 | RegisterWizard(wizProject, _T("glfw"), _T("GLFW project"), _T("2D/3D Graphics")); 35 | RegisterWizard(wizProject, _T("glut"), _T("GLUT project"), _T("2D/3D Graphics")); 36 | RegisterWizard(wizProject, _T("gtk"), _T("GTK+ project"), _T("GUI")); 37 | RegisterWizard(wizProject, _T("irrlicht"), _T("Irrlicht project"), _T("2D/3D Graphics")); 38 | RegisterWizard(wizProject, _T("java"), _T("Java application"), _T("Java")); 39 | RegisterWizard(wizProject, _T("lf"), _T("Lightfeather project"), _T("2D/3D Graphics")); 40 | RegisterWizard(wizProject, _T("matlab_csf"), _T("Matlab project"), _T("Console")); 41 | RegisterWizard(wizProject, _T("opencv"), _T("OpenCV project"), _T("Console")); 42 | RegisterWizard(wizProject, _T("opengl"), _T("OpenGL project"), _T("2D/3D Graphics")); 43 | RegisterWizard(wizProject, _T("ogre"), _T("Ogre project"), _T("2D/3D Graphics")); 44 | RegisterWizard(wizProject, _T("plugins"), _T("Code::Blocks plugin"), _T("Code::Blocks")); 45 | RegisterWizard(wizProject, _T("qt4"), _T("QT4 project"), _T("GUI")); 46 | RegisterWizard(wizProject, _T("qt4dll"), _T("QT4 (shared) project"), _T("GUI")); 47 | RegisterWizard(wizProject, _T("qt5"), _T("QT5 project"), _T("GUI")); 48 | RegisterWizard(wizProject, _T("sdl"), _T("SDL project"), _T("2D/3D Graphics")); 49 | RegisterWizard(wizProject, _T("sdl2"), _T("SDL2 project"), _T("2D/3D Graphics")); 50 | RegisterWizard(wizProject, _T("sfml"), _T("SFML project"), _T("2D/3D Graphics")); 51 | if (PLATFORM == PLATFORM_MSW) 52 | RegisterWizard(wizProject, _T("smartwin"), _T("SmartWin project"), _T("GUI")); 53 | RegisterWizard(wizProject, _T("staticlib"), _T("Static library"), _T("Console")); 54 | if (PLATFORM == PLATFORM_MSW) 55 | RegisterWizard(wizProject, _T("stlport"), _T("STL port application"), _T("Console")); 56 | RegisterWizard(wizProject, _T("sharedlib"), _T("Shared library"), _T("Console")); 57 | if (PLATFORM == PLATFORM_MSW) 58 | RegisterWizard(wizProject, _T("win32gui"), _T("Win32 GUI project"), _T("GUI")); 59 | RegisterWizard(wizProject, _T("wxwidgets"), _T("wxWidgets project"), _T("GUI")); 60 | 61 | // 62 | // build target wizards 63 | // 64 | RegisterWizard(wizTarget, _T("console"), _T("Console"), _T("Console")); 65 | RegisterWizard(wizTarget, _T("staticlib"), _T("Static library"), _T("Console")); 66 | if (PLATFORM == PLATFORM_MSW) 67 | RegisterWizard(wizTarget, _T("dll"), _T("Dynamic Link Library"), _T("Console")); 68 | RegisterWizard(wizTarget, _T("wxwidgets"), _T("wxWidgets"), _T("GUI")); 69 | 70 | RegisterWizard(wizProject, _T("arduino"), _T("Arduino Project"), _T("Embedded Systems")); 71 | RegisterWizard(wizProject, _T("arm"), _T("ARM Project"), _T("Embedded Systems")); 72 | RegisterWizard(wizProject, _T("avr"), _T("AVR Project"), _T("Embedded Systems")); 73 | RegisterWizard(wizProject, _T("msp430"), _T("MSP430 Project"), _T("Embedded Systems")); 74 | RegisterWizard(wizProject, _T("tricore"), _T("TriCore Project"), _T("Embedded Systems")); 75 | RegisterWizard(wizProject, _T("ppc"), _T("PowerPC Project"), _T("Embedded Systems")); 76 | RegisterWizard(wizProject, _T("mcs51"), _T("MCS51 Project"), _T("Embedded Systems")); 77 | // 78 | // file wizards 79 | // 80 | RegisterWizard(wizFiles, _T("empty_file"), _T("Empty file"), _T("C/C++")); 81 | RegisterWizard(wizFiles, _T("c_file"), _T("C/C++ source"), _T("C/C++")); 82 | RegisterWizard(wizFiles, _T("d_source"), _T("D source"), _T("D language")); 83 | RegisterWizard(wizFiles, _T("h_file"), _T("C/C++ header"), _T("C/C++")); 84 | RegisterWizard(wizFiles, _T("fortran/file"), _T("Fortran source"), _T("Fortran")); 85 | RegisterWizard(wizFiles, _T("java/file"), _T("Java source"), _T("Java")); 86 | } 87 | 88 | function RegisterWizard(type, folder, title, category) 89 | { 90 | // syntax: 91 | // AddWizard(type, title, category, script, template_png, wizard_png, xrc) 92 | 93 | Wizard.AddWizard(type, 94 | title, 95 | category, 96 | folder + _T("/wizard.script"), 97 | folder + _T("/logo.png"), 98 | folder + _T("/wizard.png"), 99 | folder + _T("/wizard.xrc")); 100 | } 101 | -------------------------------------------------------------------------------- /CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/exec/android-elf-cleaner32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Code-Blocks-Android-NDK/bd65ca4424728887d86a6c267de233ae58373f1d/CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/exec/android-elf-cleaner32.exe -------------------------------------------------------------------------------- /CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/exec/cbp2ndk32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Code-Blocks-Android-NDK/bd65ca4424728887d86a6c267de233ae58373f1d/CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/exec/cbp2ndk32.exe -------------------------------------------------------------------------------- /CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/files/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Code::Blocks + Android NDK project template 5 | # Copyright (c) 2016-2019 PS 6 | # HOWTO: https://clnviewer.github.io/Code-Blocks-Android-NDK/ 7 | # 8 | # - No root device! 9 | # - Build Debug (NDK toolchain) 10 | # - Build Release (NDK toolchain) 11 | # - Run from device 12 | # - Debug from device. 13 | # - Auto start/stop gdbserverfrom device. 14 | # - No wrappers from Gradle/Java code required, works directly with the device. 15 | # - Advanced project export to Android.mk file format, possible using utility cbp2ndk. 16 | # 17 | # Permission is hereby granted, free of charge, to any person obtaining a copy 18 | # of this software and associated documentation files (the "Software"), to deal 19 | # in the Software without restriction, including without limitation the rights 20 | # to use, copy, modify, merge, publish, distribute, sub license, and/or sell 21 | # copies of the Software, and to permit persons to whom the Software is 22 | # furnished to do so, subject to the following conditions: 23 | # 24 | # The above copyright notice and this permission notice shall be included in all 25 | # copies or substantial portions of the Software. 26 | # 27 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 30 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 | # SOFTWARE. 34 | 35 | # Variables PLATFORM* to Application.mk 36 | 37 | PLATFORM_ABI := $(SC_NDK_ABI) 38 | PLATFORM_API := $(SC_NDK_API) 39 | PLATFORM_STL := c++_static 40 | PLATFORM_SCRIPT := Android.mk 41 | PLATFORM_OPTIM := 42 | 43 | # Variables local 44 | 45 | DIR_UTILS := $(SC_BIN_PATH) 46 | DIR_NDKROOT := $(SC_NDK_DIR) 47 | DIR_PROJECT := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) 48 | STR_BUILDTAG := $(filter-out $@,$(MAKECMDGOALS)) 49 | STR_BUILDOPT := 50 | 51 | ifeq ($(OS),Windows_NT) 52 | DIR_CONFCBP := $(shell dir *.cbp | findstr .cbp) 53 | else 54 | DIR_CONFCBP := $(shell find $("./") -name '*.cbp') 55 | endif 56 | 57 | ifneq ($(PLATFORM_ABI),all) 58 | PLATFORM_ABI = armeabi-v7a 59 | endif 60 | 61 | ifneq ($(ANALIZE),) 62 | STR_BUILDOPT += NDK_ANALIZE=1 63 | endif 64 | 65 | ifeq ($(STR_BUILDTAG),Debug) 66 | STR_BUILDOPT += V=1 NDK_DEBUG=1 67 | PLATFORM_OPTIM = debug 68 | else 69 | STR_BUILDOPT += -j 4 70 | endif 71 | 72 | all: setndk buildndk 73 | Debug: setndk buildndk adbsetup adbdebug buildscript rundebug 74 | Release: setndk buildndk adbsetup adbexec buildscript 75 | cleanDebug: setndk clean 76 | cleanRelease: setndk clean 77 | cleanall: setndk clean 78 | 79 | setndk: 80 | @echo '==== SET C::B NDK -> $(SC_NDK_API) -> $(SC_NDK_ABI) -> active device: [ $(PLATFORM_ABI) ] ====' 81 | @$(DIR_UTILS)/exec/cbp2ndk32.exe -t $(STR_BUILDTAG) -c $(DIR_CONFCBP) --api $(PLATFORM_API) --abi $(PLATFORM_ABI) --ndkopt $(PLATFORM_OPTIM) 82 | -include $(PLATFORM_SCRIPT) 83 | 84 | buildndk: 85 | @echo '==== Build $(STR_BUILDTAG) -> $(PLATFORM_ABI) platform -> $(SC_NDK_API) API ====' 86 | @Cmd.exe /C $(DIR_NDKROOT)\ndk-build.cmd NDK_APPLICATION_MK=$(DIR_PROJECT)Application.mk NDK_PROJECT_PATH=$(DIR_PROJECT) $(STR_BUILDOPT) 87 | 88 | clean: 89 | @echo '==== Clean ====' 90 | @Cmd.exe /C $(DIR_NDKROOT)\ndk-build.cmd NDK_APPLICATION_MK=$(DIR_PROJECT)Application.mk NDK_PROJECT_PATH=$(DIR_PROJECT) clean 91 | @Cmd.exe /C adb.exe shell rm -f /data/local/tmp/$(LOCAL_MODULE) 92 | 93 | adbsetup: 94 | @echo '==== ADB SETUP: [ $(PLATFORM_ABI) ] ====' 95 | Cmd.exe /C $(DIR_UTILS)/exec/android-elf-cleaner32.exe $(DIR_PROJECT)libs\$(PLATFORM_ABI)\$(LOCAL_MODULE) 96 | Cmd.exe /C adb.exe push $(DIR_PROJECT)libs\$(PLATFORM_ABI)\$(LOCAL_MODULE) /data/local/tmp/$(LOCAL_MODULE) 97 | Cmd.exe /C adb.exe shell /system/bin/chmod 0777 /data/local/tmp/$(LOCAL_MODULE) 98 | 99 | adbexec: 100 | @echo '==== ADB RUN: [ $(PLATFORM_ABI) ] ====' 101 | @Cmd.exe /C adb.exe shell /data/local/tmp/$(LOCAL_MODULE) $(CBP2NDK_CMDLINE) 102 | 103 | adbdebug: 104 | @echo '==== GDB Debug: [ $(PLATFORM_ABI) ] ====' 105 | @Cmd.exe /C adb.exe push $(DIR_PROJECT)libs\$(PLATFORM_ABI)\gdb.setup /data/local/tmp/gdb.setup 106 | @Cmd.exe /C adb.exe push $(DIR_PROJECT)libs\$(PLATFORM_ABI)\gdbserver /data/local/tmp/gdbserver 107 | @Cmd.exe /C adb.exe shell /system/bin/chmod 0777 /data/local/tmp/gdbserver 108 | 109 | rundebug: 110 | @Cmd.exe /C DebugRemote.cmd 111 | 112 | buildscript: 113 | ifeq (,$(wildcard ./RunRemote.cmd)) 114 | @echo "adb.exe shell /data/local/tmp/$(LOCAL_MODULE) $(CBP2NDK_CMDLINE)" >RunRemote.cmd 115 | endif 116 | ifeq (,$(wildcard ./DebugRemote.cmd)) 117 | @echo "adb.exe forward tcp:59999 tcp:59999" >DebugRemote.cmd 118 | @echo "start \"$(PLATFORM_ABI) GDB server\" /MIN adb.exe shell /data/local/tmp/gdbserver :59999 /data/local/tmp/$(LOCAL_MODULE) $(CBP2NDK_CMDLINE)" >>DebugRemote.cmd 119 | @echo "exit" >>DebugRemote.cmd 120 | endif 121 | 122 | .PHONY: clean all 123 | 124 | -------------------------------------------------------------------------------- /CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/files/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | /* 9 | /// NDK Android native Project 10 | HOWTO: https://clnviewer.github.io/Code-Blocks-Android-NDK/ 11 | AOSP heasers: https://github.com/ClnViewer/android-platform-headers/ 12 | android-elf-cleaner: https://github.com/ClnViewer/termux-elf-cleaner/ 13 | cbp2ndk: https://github.com/ClnViewer/Code-Blocks-Android-NDK/tree/master/cbp2ndk/ 14 | 15 | */ 16 | 17 | int main(void) 18 | { 19 | int a = 18; 20 | int b = a; 21 | 22 | std::cout << std::endl << "\tHello Android! " << b << " - " << a << std::endl << std::endl; 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Code-Blocks-Android-NDK/bd65ca4424728887d86a6c267de233ae58373f1d/CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/logo.png -------------------------------------------------------------------------------- /CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/wizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Code-Blocks-Android-NDK/bd65ca4424728887d86a6c267de233ae58373f1d/CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/wizard.png -------------------------------------------------------------------------------- /CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/wizard.script: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Code::Blocks new project wizard script 4 | // 5 | // Project: NDK Android native Project 6 | // Author: PS 7 | // HOWTO: https://clnviewer.github.io/Code-Blocks-Android-NDK/ 8 | // 9 | // Description: 10 | // Currently the script has been converted to support building with 11 | // a makefile but will eventually support building in the IDE as well. 12 | // 13 | //////////////////////////////////////////////////////////////////////////////// 14 | 15 | // Global Vars 16 | NdkPathDefault <- _T("$(#ndk)"); 17 | AospPathDefault <- _T("$(#aosp)"); 18 | str_NdkPath <- _T(""); 19 | str_AospPath <- _T(""); 20 | str_BinApi <- _T(""); 21 | str_BinAbi <- _T(""); 22 | api_level <- 0; 23 | abi_level <- 0; 24 | 25 | function BeginWizard() 26 | { 27 | local wiz_type = Wizard.GetWizardType(); 28 | 29 | if (wiz_type == wizProject) 30 | { 31 | local intro_msg = _T("Welcome to the NDK Android native Project Wizard\n\n" + 32 | "This wizard will guide you to create a new NDK project.\n\n" + 33 | "When you 're ready to proceed, please click \"Next\"\n\n" + 34 | "This wizard is created by PS.\n" + 35 | "For details see\nhttps://clnviewer.github.io/Code-Blocks-Android-NDK/\n\n" + 36 | "Require binary files:\n" + 37 | "https://github.com/ClnViewer/termux-elf-cleaner/\n" + 38 | "https://github.com/ClnViewer/Code-Blocks-Android-NDK/tree/master/cbp2ndk/"); 39 | 40 | local hdkpath_descr = _T("Please select the location of Android NDK on your computer.\n" + 41 | "This is the top-level folder where Android NDK was installed.\n" + 42 | "Download:\nnhttps://clnviewer.github.io/Code-Blocks-Android-NDK/"); 43 | 44 | local aosppath_descr = _T("Please select the location of Android AOSP header on your computer.\n" + 45 | "This is the top-level folder where Android AOSP was installed.\n" + 46 | "Download:\nhttps://github.com/ClnViewer/android-platform-headers/"); 47 | 48 | local str_NDK_API_level = _T("android-20;" + 49 | "android-21;" + 50 | "android-22;" + 51 | "android-23;" + 52 | "android-24;" + 53 | "android-25;" + 54 | "android-26;" + 55 | "android-27;" + 56 | "android-28;" + 57 | "android-29;" + 58 | "android-30;" + 59 | "android-31;" 60 | ); 61 | 62 | local str_NDK_ABI_platform = _T("all;" + 63 | "armeabi-v7a;" + 64 | "arm64-v8a;" + 65 | "x86;" + 66 | "x86_64;" 67 | ); 68 | 69 | Wizard.AddInfoPage(_T("NDK Android native Intro"), intro_msg); 70 | Wizard.AddGenericSelectPathPage(_T("NdkPath"), hdkpath_descr, _T("Require - select Android NDK path location:"), NdkPathDefault); 71 | Wizard.AddGenericSelectPathPage(_T("AospPath"), aosppath_descr, _T("Optional - select Android AOSP header path location:"), AospPathDefault); 72 | Wizard.AddGenericSingleChoiceListPage(_T("NdkApi"), _T("Please select Android NDK API level"), str_NDK_API_level , api_level); 73 | Wizard.AddGenericSingleChoiceListPage(_T("NdkAbi"), _T("Please select Android NDK ABI platform"), str_NDK_ABI_platform, abi_level); 74 | Wizard.AddProjectPathPage(); 75 | } 76 | else 77 | print(wiz_type); 78 | } 79 | 80 | 81 | //////////////////////////////////////////////////////////////////////////////// 82 | function OnLeave_NdkPath(fwd) 83 | { 84 | if (fwd) 85 | { 86 | str_NdkPath = Wizard.GetTextControlValue(_T("txtFolder")); 87 | if (!IO.FileExists(str_NdkPath + _T("/sysroot/usr/include/jni.h"))) 88 | { 89 | ShowError(_T("Invalid NDK path, {NDK directory}/sysroot/usr/include/jni.h NOT found")); 90 | return false; 91 | } 92 | } 93 | return true; 94 | } 95 | 96 | function OnLeave_AospPath(fwd) 97 | { 98 | if (fwd) 99 | { 100 | str_AospPath = Wizard.GetTextControlValue(_T("txtFolder")); 101 | } 102 | return true; 103 | } 104 | 105 | function OnLeave_NdkApi(fwd) 106 | { 107 | str_BinApi = Wizard.GetListboxStringSelections(_T("GenericChoiceList")); 108 | if (str_BinApi.IsEmpty()) 109 | { 110 | ShowWarning(_T("No select Android API!")); 111 | return false; 112 | } 113 | str_BinApi.RemoveLast(1); 114 | return true; 115 | } 116 | 117 | function OnLeave_NdkAbi(fwd) 118 | { 119 | str_BinAbi = Wizard.GetListboxStringSelections(_T("GenericChoiceList")); 120 | if (str_BinAbi.IsEmpty()) 121 | { 122 | ShowWarning(_T("No select Android ABI!")); 123 | return false; 124 | } 125 | str_BinAbi.RemoveLast(1); 126 | return true; 127 | } 128 | 129 | //////////////////////////////////////////////////////////////////////////////// 130 | 131 | function GetFilesDir() 132 | { 133 | local result = _T("ndk_android/files"); 134 | return result; 135 | } 136 | 137 | // setup the already created project 138 | function SetupProject(project) 139 | { 140 | local util_path = Wizard.FindTemplateFile(_T("ndk_android")); 141 | if (util_path.IsEmpty()) 142 | { 143 | ShowWarning(_T("No binary utilites found, install cbp2ndk32.exe and android-elf-cleaner32.exe!")); 144 | return false; 145 | } 146 | 147 | project.SetVar(_T("NDK_API"), str_BinApi, false); 148 | project.SetVar(_T("NDK_ABI"), str_BinAbi, false); 149 | project.SetVar(_T("NDK_DIR"), str_NdkPath, false); 150 | project.SetVar(_T("AOSP_DIR"), str_AospPath, false); 151 | project.SetVar(_T("UTIL_DIR"), util_path + _T("/exec"), false); 152 | 153 | // Project make & prebuild commands 154 | local pb_cleanbin = util_path + _T("/exec/android-elf-cleaner32.exe $(PROJECT_DIR)libs/") + str_BinAbi + _T("/$(TARGET_OUTPUT_BASENAME)"); 155 | local mk_variable = _T("SC_BIN_PATH=\"") + util_path + _T("\" SC_NDK_API=\"") + str_BinApi + _T("\" SC_NDK_ABI=\"") + str_BinAbi + _T("\" SC_NDK_DIR=\"") + str_NdkPath + _T("\""); 156 | if (!str_AospPath.IsEmpty()) 157 | { 158 | mk_variable += _T(" SC_AOSP_DIR=\"") + str_AospPath + _T("\""); 159 | } 160 | 161 | // Project options 162 | project.AddIncludeDir(str_NdkPath + _T("/sysroot/usr/include")); 163 | if (!str_AospPath.IsEmpty()) 164 | { 165 | project.AddIncludeDir(str_AospPath + _T("/system/core/include")); 166 | project.AddIncludeDir(str_AospPath + _T("/frameworks/base/include")); 167 | project.AddIncludeDir(str_AospPath + _T("/frameworks/native/include")); 168 | project.AddIncludeDir(str_AospPath + _T("/hardware/libhardware/include")); 169 | } 170 | 171 | project.AddCompilerOption(_T("-Wall")); 172 | project.AddCompilerOption(_T("-Wno-unknown-pragmas")); 173 | project.AddCompilerOption(_T("-fexceptions")); 174 | project.AddCompilerOption(_T("-D__ANDROID_API_PLATFORM__=\"$(TARGET_PLATFORM)\"")); 175 | //project.AddLinkerOption(_T("-llog")); 176 | //project.CallHooks(true); 177 | 178 | // Debugger set (not property works) 179 | project.AddToExtensions(_T("debugger1/remote_debugging:target=Debug")); 180 | project.AddToExtensions(_T("debugger1/remote_debugging/options:ip_address=127.0.0.1")); 181 | project.AddToExtensions(_T("debugger1/remote_debugging/options:ip_port=59999")); 182 | project.AddToExtensions(_T("debugger1/remote_debugging/options:extended_remote=1")); 183 | project.AddToExtensions(_T("debugger1/remote_debugging/options:additional_cmds_before=\"set solib-search-path obj/local/") + str_BinAbi + _T(" file obj/local/") + str_BinAbi + _T("/$(TARGET_OUTPUT_BASENAME) \"")); 184 | project.AddToExtensions(_T("debugger1/search_path:add=obj/local/") + str_BinAbi); 185 | 186 | // We are using a custom makefile 187 | project.SetMakefile(_T("Makefile")); 188 | project.SetMakefileCustom(true); 189 | project.AddCommandsAfterBuild(pb_cleanbin); 190 | WarningsOn(project, Wizard.GetCompilerID()); 191 | 192 | // Debug build target 193 | local target = project.GetBuildTarget(Wizard.GetDebugName()); 194 | if (!IsNull(target)) 195 | { 196 | target.SetTargetType(ttNative); 197 | target.SetTargetFilenameGenerationPolicy(tgfpPlatformDefault, tgfpNone); 198 | target.SetOutputFilename(Wizard.GetDebugOutputDir() + Wizard.GetProjectName()); 199 | // Make rules 200 | target.SetMakeCommandFor(mcClean, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -f $makefile clean$target ") + mk_variable); 201 | target.SetMakeCommandFor(mcDistClean, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -f $makefile distclean$target ") + mk_variable); 202 | target.SetMakeCommandFor(mcBuild, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -f $makefile $target ") + mk_variable); 203 | target.SetMakeCommandFor(mcCompileFile, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -f $makefile $file ") + mk_variable); 204 | target.SetMakeCommandFor(mcAskRebuildNeeded, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -q -f $makefile $target ") + mk_variable); 205 | target.SetMakeCommandFor(mcSilentBuild, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -f $makefile $target ") + mk_variable + _T(" > $(CMD_NULL)")); 206 | } 207 | 208 | // Release build target 209 | target = project.GetBuildTarget(Wizard.GetReleaseName()); 210 | if (!IsNull(target)) 211 | { 212 | target.SetTargetType(ttNative); 213 | target.SetTargetFilenameGenerationPolicy(tgfpPlatformDefault, tgfpNone); 214 | target.SetOutputFilename(Wizard.GetReleaseOutputDir() + Wizard.GetProjectName()); 215 | // Make rules 216 | target.SetMakeCommandFor(mcClean, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -f $makefile clean$target ") + mk_variable); 217 | target.SetMakeCommandFor(mcDistClean, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -f $makefile distclean$target ") + mk_variable); 218 | target.SetMakeCommandFor(mcBuild, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -f $makefile $target ") + mk_variable); 219 | target.SetMakeCommandFor(mcCompileFile, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -f $makefile $file ") + mk_variable); 220 | target.SetMakeCommandFor(mcAskRebuildNeeded, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -q -f $makefile $target ") + mk_variable); 221 | target.SetMakeCommandFor(mcSilentBuild, str_NdkPath + _T("/prebuilt/windows/bin/make.exe -f $makefile $target ") + mk_variable + _T(" > $(CMD_NULL)")); 222 | } 223 | return true; 224 | } 225 | -------------------------------------------------------------------------------- /CB-Template/hdk-main.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #if defined(__cplusplus) 6 | extern "C" { 7 | #endif 8 | 9 | void test(int); 10 | 11 | #if defined(__cplusplus) 12 | } 13 | #endif 14 | -------------------------------------------------------------------------------- /CB-Template/ndk-main.c: -------------------------------------------------------------------------------- 1 | 2 | #include "hdk-main.h" 3 | 4 | /* 5 | DEBUG GDB test, 6 | manual run gdb.exe and type: 7 | set solib-search-path obj/local/armeabi-v7a 8 | file obj/local/armeabi-v7a/hello_world 9 | target remote localhost:59999 10 | b test 11 | c 12 | n 13 | q 14 | */ 15 | 16 | int main(void) 17 | { 18 | int a = 18; 19 | int b = a; 20 | 21 | test(b); 22 | printf("Hello world! (%d)\n", b); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /CB-Template/ndk-test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "hdk-main.h" 3 | #include 4 | 5 | extern "C" void test(int b) 6 | { 7 | __android_log_print(ANDROID_LOG_DEBUG , "~~~~~~", "log %i", b); 8 | } 9 | -------------------------------------------------------------------------------- /CBTemplate.workspace: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 NewView 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![HOWTO RU](https://img.shields.io/badge/HOWTO-DOC-brightgreen.svg?style=flat)](https://clnviewer.github.io/Code-Blocks-Android-NDK/) 2 | [![C::B project template](https://img.shields.io/badge/CodeBlocks-template-brightgreen.svg?style=flat)](https://github.com/ClnViewer/Code-Blocks-Android-NDK/tree/master/CB-Template) 3 | [![License MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg?style=flat)](https://github.com/ClnViewer/Code-Blocks-Android-NDK/blob/master/LICENSE) 4 | 5 | [![Build Travis](https://travis-ci.com/ClnViewer/Code-Blocks-Android-NDK.svg)](https://travis-ci.com/ClnViewer/Code-Blocks-Android-NDK) 6 | [![Repo size](https://img.shields.io/github/repo-size/ClnViewer/Code-Blocks-Android-NDK.svg?style=flat)](https://github.com/ClnViewer/Code-Blocks-Android-NDK/) 7 | [![Code size](https://img.shields.io/github/languages/code-size/ClnViewer/Code-Blocks-Android-NDK.svg?style=flat)](https://github.com/ClnViewer/Code-Blocks-Android-NDK/) 8 | 9 | 10 | # Code::Blocks Android NDK 11 | 12 | `Code::Blocks` + `Android NDK` project template [__HOWTO__](https://clnviewer.github.io/Code-Blocks-Android-NDK/) 13 | `Code::Blocks Template` __auto installation__ [EN](https://clnviewer.github.io/Code-Blocks-Android-NDK/CBNDKAUTOINSTALL.EN.html) | [RU](https://clnviewer.github.io/Code-Blocks-Android-NDK/CBNDKAUTOINSTALL.RU.html) | [exe](https://clnviewer.github.io/Code-Blocks-Android-NDK/CodeBlocksNdkTemplate.exe) 14 | `Code::Blocks Template utilities` __cbp2ndk__ [EN](https://clnviewer.github.io/Code-Blocks-Android-NDK/CBP2NDK.EN.html) | [RU](https://clnviewer.github.io/Code-Blocks-Android-NDK/CBP2NDK.RU.html) | [zip](https://clnviewer.github.io/Code-Blocks-Android-NDK/cbp2ndk.zip) 15 | `Code::Blocks Template utilities` [android-elf-cleaner](https://clnviewer.github.io/Code-Blocks-Android-NDK/) | [zip](https://clnviewer.github.io/Code-Blocks-Android-NDK/android-elf-cleaner.zip) 16 | 17 | 18 | ### Support: 19 | 20 | - No root device! 21 | - Build Debug (NDK toolchain). 22 | - Build Release (NDK toolchain). 23 | - Run from device. 24 | - Debug from device. 25 | - Auto start/stop `gdbserver` from device. 26 | - No wrappers from `Gradle/Java` code required, works directly with the device. 27 | - Advanced project export to `Android.mk` file format, possible using utility [cbp2ndk](cbp2ndk/). 28 | 29 | 30 | ![Build and Run NDK Hello Word screen](docs/img/Image10.png) 31 | 32 | ![Build and Debug NDK Hello Word screen](docs/img/Image14.png) 33 | 34 | 35 | 36 | ## License 37 | 38 | _MIT_ 39 | 40 | -------------------------------------------------------------------------------- /android-elf-cleaner/android-elf-cleaner.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 59 | 60 | -------------------------------------------------------------------------------- /android-elf-cleaner/android-elf-cleaner.cpp: -------------------------------------------------------------------------------- 1 | 2 | /// Windows MinGW build version adapted from PS 3 | /// https://github.com/termux/termux-elf-cleaner 4 | /// using mapping: https://github.com/mandreyel/mio 5 | 6 | #include "mio.hpp" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #ifndef _WIN32 14 | #include 15 | #endif 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #ifndef __ANDROID_API__ 22 | #define __ANDROID_API__ 21 23 | #endif 24 | 25 | // Include a local elf.h copy as not all platforms have it. 26 | #include "elf.h" 27 | 28 | #define DT_GNU_HASH 0x6ffffef5 29 | #define DT_VERSYM 0x6ffffff0 30 | #define DT_FLAGS_1 0x6ffffffb 31 | #define DT_VERNEEDED 0x6ffffffe 32 | #define DT_VERNEEDNUM 0x6fffffff 33 | 34 | #define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ 35 | #define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ 36 | #define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ 37 | 38 | #if __ANDROID_API__ < 23 39 | #define SUPPORTED_DT_FLAGS_1 (DF_1_NOW | DF_1_GLOBAL) 40 | #else 41 | // The supported DT_FLAGS_1 values as of Android 6.0. 42 | #define SUPPORTED_DT_FLAGS_1 (DF_1_NOW | DF_1_GLOBAL | DF_1_NODELETE) 43 | #endif 44 | 45 | template 48 | bool process_elf(uint8_t* bytes, size_t elf_file_size, char const* file_name) 49 | { 50 | if (sizeof(ElfSectionHeaderType) > elf_file_size) 51 | { 52 | fprintf(stderr, "termux-elf-cleaner: Elf header for '%s' would end at %zu but file size only %zu\n", file_name, sizeof(ElfSectionHeaderType), elf_file_size); 53 | return false; 54 | } 55 | ElfHeaderType* elf_hdr = reinterpret_cast(bytes); 56 | 57 | size_t last_section_header_byte = elf_hdr->e_shoff + sizeof(ElfSectionHeaderType) * elf_hdr->e_shnum; 58 | if (last_section_header_byte > elf_file_size) 59 | { 60 | fprintf(stderr, "termux-elf-cleaner: Section header for '%s' would end at %zu but file size only %zu\n", file_name, last_section_header_byte, elf_file_size); 61 | return false; 62 | } 63 | ElfSectionHeaderType* section_header_table = reinterpret_cast(bytes + elf_hdr->e_shoff); 64 | 65 | for (unsigned int i = 1; i < elf_hdr->e_shnum; i++) 66 | { 67 | ElfSectionHeaderType* section_header_entry = section_header_table + i; 68 | if (section_header_entry->sh_type == SHT_DYNAMIC) 69 | { 70 | size_t const last_dynamic_section_byte = section_header_entry->sh_offset + section_header_entry->sh_size; 71 | if (last_dynamic_section_byte > elf_file_size) 72 | { 73 | fprintf(stderr, "termux-elf-cleaner: Dynamic section for '%s' would end at %zu but file size only %zu\n", file_name, last_dynamic_section_byte, elf_file_size); 74 | return false; 75 | } 76 | 77 | size_t const dynamic_section_entries = section_header_entry->sh_size / sizeof(ElfDynamicSectionEntryType); 78 | ElfDynamicSectionEntryType* const dynamic_section = 79 | reinterpret_cast(bytes + section_header_entry->sh_offset); 80 | 81 | unsigned int last_nonnull_entry_idx = 0; 82 | for (unsigned int j = dynamic_section_entries - 1; j > 0; j--) 83 | { 84 | ElfDynamicSectionEntryType* dynamic_section_entry = dynamic_section + j; 85 | if (dynamic_section_entry->d_tag != DT_NULL) 86 | { 87 | last_nonnull_entry_idx = j; 88 | break; 89 | } 90 | } 91 | 92 | for (unsigned int j = 0; j < dynamic_section_entries; j++) 93 | { 94 | ElfDynamicSectionEntryType* dynamic_section_entry = dynamic_section + j; 95 | char const* removed_name = NULL; 96 | switch (dynamic_section_entry->d_tag) 97 | { 98 | #if __ANDROID_API__ <= 21 99 | case DT_GNU_HASH: 100 | removed_name = "DT_GNU_HASH"; 101 | break; 102 | #endif 103 | #if __ANDROID_API__ < 23 104 | case DT_VERSYM: 105 | removed_name = "DT_VERSYM"; 106 | break; 107 | case DT_VERNEEDED: 108 | removed_name = "DT_VERNEEDED"; 109 | break; 110 | case DT_VERNEEDNUM: 111 | removed_name = "DT_VERNEEDNUM"; 112 | break; 113 | case DT_VERDEF: 114 | removed_name = "DT_VERDEF"; 115 | break; 116 | case DT_VERDEFNUM: 117 | removed_name = "DT_VERDEFNUM"; 118 | break; 119 | #endif 120 | case DT_RPATH: 121 | removed_name = "DT_RPATH"; 122 | break; 123 | #if __ANDROID_API__ < 24 124 | case DT_RUNPATH: 125 | removed_name = "DT_RUNPATH"; 126 | break; 127 | #endif 128 | } 129 | if (removed_name != NULL) 130 | { 131 | printf("termux-elf-cleaner: Removing the %s dynamic section entry from '%s'\n", removed_name, file_name); 132 | // Tag the entry with DT_NULL and put it last: 133 | dynamic_section_entry->d_tag = DT_NULL; 134 | // Decrease j to process new entry index: 135 | std::swap(dynamic_section[j--], dynamic_section[last_nonnull_entry_idx--]); 136 | } 137 | else if (dynamic_section_entry->d_tag == DT_FLAGS_1) 138 | { 139 | // Remove unsupported DF_1_* flags to avoid linker warnings. 140 | int orig_d_val = 141 | dynamic_section_entry->d_un.d_val; 142 | int new_d_val = 143 | (orig_d_val & SUPPORTED_DT_FLAGS_1); 144 | if (new_d_val != orig_d_val) 145 | { 146 | printf("termux-elf-cleaner: Replacing unsupported DF_1_* flags %llu with %llu in '%s'\n", 147 | (unsigned long long) orig_d_val, 148 | (unsigned long long) new_d_val, 149 | file_name); 150 | dynamic_section_entry->d_un.d_val = new_d_val; 151 | } 152 | } 153 | } 154 | } 155 | #if __ANDROID_API__ < 23 156 | else if (section_header_entry->sh_type == SHT_GNU_verdef || 157 | section_header_entry->sh_type == SHT_GNU_verneed || 158 | section_header_entry->sh_type == SHT_GNU_versym) 159 | { 160 | printf("termux-elf-cleaner: Removing version section from '%s'\n", file_name); 161 | section_header_entry->sh_type = SHT_NULL; 162 | } 163 | #endif 164 | } 165 | return true; 166 | } 167 | 168 | 169 | int main(int argc, char const** argv) 170 | { 171 | if (argc < 2 || (argc == 2 && strcmp(argv[1], "-h")==0)) 172 | { 173 | fprintf(stderr, "usage: %s \n", argv[0]); 174 | fprintf(stderr, "\nProcesses ELF files to remove unsupported section types\n" 175 | "and dynamic section entries which the Android linker (API %d)\nwarns about.\n", 176 | __ANDROID_API__); 177 | return 127; 178 | } 179 | 180 | for (int i = 1; i < argc; i++) 181 | { 182 | char const *file_name = argv[i]; 183 | 184 | # ifdef _WIN32 185 | 186 | std::error_code error{}; 187 | mio::mmap_sink rw_mmap = mio::make_mmap_sink(file_name, 0, mio::map_entire_file, error); 188 | 189 | if (error) 190 | { 191 | const auto& errmsg = error.message(); 192 | printf("error mapping file: %s, exiting...\n", errmsg.c_str()); 193 | return error.value(); 194 | } 195 | 196 | void *mem = &rw_mmap[0]; 197 | size_t const file_size = rw_mmap.size(); 198 | 199 | # else 200 | 201 | int fd = open(file_name, O_RDWR); 202 | if (fd < 0) 203 | { 204 | char* error_message; 205 | if (asprintf(&error_message, "open(\"%s\")", file_name) == -1) 206 | error_message = (char*) "open()"; 207 | perror(error_message); 208 | return 1; 209 | } 210 | 211 | struct stat st; 212 | if (fstat(fd, &st) < 0) 213 | { 214 | perror("fstat()"); 215 | return 1; 216 | } 217 | 218 | size_t const file_size = static_cast(st.st_size); 219 | 220 | if (file_size < sizeof(Elf32_Ehdr)) 221 | { 222 | close(fd); 223 | continue; 224 | } 225 | 226 | void* mem = mmap(0, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 227 | if (mem == MAP_FAILED) 228 | { 229 | perror("mmap()"); 230 | return 1; 231 | } 232 | # endif 233 | 234 | uint8_t* bytes = reinterpret_cast(mem); 235 | if (!(bytes[0] == 0x7F && bytes[1] == 'E' && bytes[2] == 'L' && bytes[3] == 'F')) 236 | { 237 | // Not the ELF magic number. 238 | # ifdef _WIN32 239 | rw_mmap.unmap(); 240 | # else 241 | munmap(mem, file_size); 242 | close(fd); 243 | # endif 244 | continue; 245 | } 246 | 247 | if (bytes[/*EI_DATA*/5] != 1) 248 | { 249 | fprintf(stderr, "termux-elf-cleaner: Not little endianness in '%s'\n", file_name); 250 | # ifdef _WIN32 251 | rw_mmap.unmap(); 252 | # else 253 | munmap(mem, file_size); 254 | close(fd); 255 | # endif 256 | continue; 257 | } 258 | 259 | uint8_t const bit_value = bytes[/*EI_CLASS*/4]; 260 | if (bit_value == 1) 261 | { 262 | if (!process_elf(bytes, file_size, file_name)) 263 | return 1; 264 | } 265 | else if (bit_value == 2) 266 | { 267 | if (!process_elf(bytes, file_size, file_name)) 268 | return 1; 269 | } 270 | else 271 | { 272 | printf("termux-elf-cleaner: Incorrect bit value %d in '%s'\n", bit_value, file_name); 273 | return 1; 274 | } 275 | 276 | # ifdef _WIN32 277 | rw_mmap.sync(error); 278 | if (error) 279 | { 280 | const auto& errmsg = error.message(); 281 | printf("error mapping sync: %s, exiting...\n", errmsg.c_str()); 282 | return error.value(); 283 | } 284 | rw_mmap.unmap(); 285 | 286 | # else 287 | 288 | if (msync(mem, file_size, MS_SYNC) < 0) 289 | { 290 | perror("msync()"); 291 | return 1; 292 | } 293 | 294 | munmap(mem, st.st_size); 295 | close(fd); 296 | # endif 297 | } 298 | return 0; 299 | } 300 | -------------------------------------------------------------------------------- /android-elf-cleaner/elf.h: -------------------------------------------------------------------------------- 1 | #ifndef ELF_H_INCLUDED 2 | #define ELF_H_INCLUDED 3 | 4 | #include 5 | 6 | /* Type for a 16-bit quantity. */ 7 | typedef uint16_t Elf32_Half; 8 | typedef uint16_t Elf64_Half; 9 | 10 | /* Types for signed and unsigned 32-bit quantities. */ 11 | typedef uint32_t Elf32_Word; 12 | typedef int32_t Elf32_Sword; 13 | typedef uint32_t Elf64_Word; 14 | typedef int32_t Elf64_Sword; 15 | 16 | /* Types for signed and unsigned 64-bit quantities. */ 17 | typedef uint64_t Elf32_Xword; 18 | typedef int64_t Elf32_Sxword; 19 | typedef uint64_t Elf64_Xword; 20 | typedef int64_t Elf64_Sxword; 21 | 22 | /* Type of addresses. */ 23 | typedef uint32_t Elf32_Addr; 24 | typedef uint64_t Elf64_Addr; 25 | 26 | /* Type of file offsets. */ 27 | typedef uint32_t Elf32_Off; 28 | typedef uint64_t Elf64_Off; 29 | 30 | /* Type for section indices, which are 16-bit quantities. */ 31 | typedef uint16_t Elf32_Section; 32 | typedef uint16_t Elf64_Section; 33 | 34 | /* Type for version symbol information. */ 35 | typedef Elf32_Half Elf32_Versym; 36 | typedef Elf64_Half Elf64_Versym; 37 | 38 | 39 | /* The ELF file header. This appears at the start of every ELF file. */ 40 | typedef struct { 41 | unsigned char e_ident[16]; /* Magic number and other info */ 42 | Elf32_Half e_type; /* Object file type */ 43 | Elf32_Half e_machine; /* Architecture */ 44 | Elf32_Word e_version; /* Object file version */ 45 | Elf32_Addr e_entry; /* Entry point virtual address */ 46 | Elf32_Off e_phoff; /* Program header table (usually follows elf header directly) file offset */ 47 | Elf32_Off e_shoff; /* Section header table (at end of file) file offset */ 48 | Elf32_Word e_flags; /* Processor-specific flags */ 49 | Elf32_Half e_ehsize; /* ELF header size in bytes */ 50 | Elf32_Half e_phentsize; /* Program header table entry size */ 51 | Elf32_Half e_phnum; /* Program header table entry count */ 52 | Elf32_Half e_shentsize; /* Section header table entry size */ 53 | Elf32_Half e_shnum; /* Section header table entry count */ 54 | Elf32_Half e_shstrndx; /* Section header string table index */ 55 | } Elf32_Ehdr; 56 | typedef struct { 57 | unsigned char e_ident[16]; /* Magic number and other info */ 58 | Elf64_Half e_type; /* Object file type */ 59 | Elf64_Half e_machine; /* Architecture */ 60 | Elf64_Word e_version; /* Object file version */ 61 | Elf64_Addr e_entry; /* Entry point virtual address */ 62 | Elf64_Off e_phoff; /* Program header table file offset */ 63 | Elf64_Off e_shoff; /* Section header table file offset */ 64 | Elf64_Word e_flags; /* Processor-specific flags */ 65 | Elf64_Half e_ehsize; /* ELF header size in bytes */ 66 | Elf64_Half e_phentsize; /* Program header table entry size */ 67 | Elf64_Half e_phnum; /* Program header table entry count */ 68 | Elf64_Half e_shentsize; /* Section header table entry size */ 69 | Elf64_Half e_shnum; /* Section header table entry count */ 70 | Elf64_Half e_shstrndx; /* Section header string table index */ 71 | } Elf64_Ehdr; 72 | 73 | /* Section header entry. The number of section entries in the file are determined by the "e_shnum" field of the ELF header.*/ 74 | typedef struct { 75 | Elf32_Word sh_name; /* Section name (string tbl index) */ 76 | Elf32_Word sh_type; /* Section type */ 77 | Elf32_Word sh_flags; /* Section flags */ 78 | Elf32_Addr sh_addr; /* Section virtual addr at execution */ 79 | Elf32_Off sh_offset; /* Section file offset */ 80 | Elf32_Word sh_size; /* Section size in bytes */ 81 | Elf32_Word sh_link; /* Link to another section */ 82 | Elf32_Word sh_info; /* Additional section information */ 83 | Elf32_Word sh_addralign; /* Section alignment */ 84 | Elf32_Word sh_entsize; /* Entry size if section holds table */ 85 | } Elf32_Shdr; 86 | typedef struct { 87 | Elf64_Word sh_name; /* Section name (string tbl index) */ 88 | Elf64_Word sh_type; /* Section type */ 89 | Elf64_Xword sh_flags; /* Section flags */ 90 | Elf64_Addr sh_addr; /* Section virtual addr at execution */ 91 | Elf64_Off sh_offset; /* Section file offset */ 92 | Elf64_Xword sh_size; /* Section size in bytes */ 93 | Elf64_Word sh_link; /* Link to another section */ 94 | Elf64_Word sh_info; /* Additional section information */ 95 | Elf64_Xword sh_addralign; /* Section alignment */ 96 | Elf64_Xword sh_entsize; /* Entry size if section holds table */ 97 | } Elf64_Shdr; 98 | 99 | /* Legal values for sh_type (section type). */ 100 | #define SHT_NULL 0 /* Section header table entry unused */ 101 | #define SHT_PROGBITS 1 /* Program data */ 102 | #define SHT_SYMTAB 2 /* Symbol table */ 103 | #define SHT_STRTAB 3 /* String table */ 104 | #define SHT_RELA 4 /* Relocation entries with addends */ 105 | #define SHT_HASH 5 /* Symbol hash table */ 106 | #define SHT_DYNAMIC 6 /* Dynamic linking information. Contains Elf32_Dyn/Elf64_Dyn entries. */ 107 | #define SHT_NOTE 7 /* Notes */ 108 | #define SHT_NOBITS 8 /* Program space with no data (bss) */ 109 | #define SHT_REL 9 /* Relocation entries, no addends */ 110 | #define SHT_SHLIB 10 /* Reserved */ 111 | #define SHT_DYNSYM 11 /* Dynamic linker symbol table */ 112 | #define SHT_INIT_ARRAY 14 /* Array of constructors */ 113 | #define SHT_FINI_ARRAY 15 /* Array of destructors */ 114 | #define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ 115 | #define SHT_GROUP 17 /* Section group */ 116 | #define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ 117 | #define SHT_NUM 19 /* Number of defined types. */ 118 | #define SHT_LOOS 0x60000000 /* Start OS-specific. */ 119 | #define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ 120 | #define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ 121 | #define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ 122 | #define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ 123 | #define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ 124 | #define SHT_SUNW_move 0x6ffffffa 125 | #define SHT_SUNW_COMDAT 0x6ffffffb 126 | #define SHT_SUNW_syminfo 0x6ffffffc 127 | #define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ 128 | #define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ 129 | #define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ 130 | #define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ 131 | #define SHT_HIOS 0x6fffffff /* End OS-specific type */ 132 | #define SHT_LOPROC 0x70000000 /* Start of processor-specific */ 133 | #define SHT_HIPROC 0x7fffffff /* End of processor-specific */ 134 | #define SHT_LOUSER 0x80000000 /* Start of application-specific */ 135 | #define SHT_HIUSER 0x8fffffff /* End of application-specific */ 136 | 137 | /* Dynamic section entry. */ 138 | typedef struct { 139 | Elf32_Sword d_tag; /* Dynamic entry type */ 140 | union { Elf32_Word d_val; Elf32_Addr d_ptr; } d_un; /* Integer or address value */ 141 | } Elf32_Dyn; 142 | typedef struct { 143 | Elf64_Sxword d_tag; /* Dynamic entry type */ 144 | union { Elf64_Xword d_val; Elf64_Addr d_ptr; } d_un; /* Integer or address value */ 145 | } Elf64_Dyn; 146 | 147 | /* Legal values for d_tag (dynamic entry type). */ 148 | #define DT_NULL 0 /* Marks end of dynamic section */ 149 | #define DT_NEEDED 1 /* Name of needed library */ 150 | #define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ 151 | #define DT_PLTGOT 3 /* Processor defined value */ 152 | #define DT_HASH 4 /* Address of symbol hash table */ 153 | #define DT_STRTAB 5 /* Address of string table */ 154 | #define DT_SYMTAB 6 /* Address of symbol table */ 155 | #define DT_RELA 7 /* Address of Rela relocs */ 156 | #define DT_RELASZ 8 /* Total size of Rela relocs */ 157 | #define DT_RELAENT 9 /* Size of one Rela reloc */ 158 | #define DT_STRSZ 10 /* Size of string table */ 159 | #define DT_SYMENT 11 /* Size of one symbol table entry */ 160 | #define DT_INIT 12 /* Address of init function */ 161 | #define DT_FINI 13 /* Address of termination function */ 162 | #define DT_SONAME 14 /* Name of shared object */ 163 | #define DT_RPATH 15 /* Library search path (deprecated) */ 164 | #define DT_SYMBOLIC 16 /* Start symbol search here */ 165 | #define DT_REL 17 /* Address of Rel relocs */ 166 | #define DT_RELSZ 18 /* Total size of Rel relocs */ 167 | #define DT_RELENT 19 /* Size of one Rel reloc */ 168 | #define DT_PLTREL 20 /* Type of reloc in PLT */ 169 | #define DT_DEBUG 21 /* For debugging; unspecified */ 170 | #define DT_TEXTREL 22 /* Reloc might modify .text */ 171 | #define DT_JMPREL 23 /* Address of PLT relocs */ 172 | #define DT_BIND_NOW 24 /* Process relocations of object */ 173 | #define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ 174 | #define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ 175 | #define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ 176 | #define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ 177 | #define DT_RUNPATH 29 /* Library search path */ 178 | #define DT_FLAGS 30 /* Flags for the object being loaded */ 179 | #define DT_ENCODING 32 /* Start of encoded range */ 180 | #define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ 181 | #define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ 182 | #define DT_NUM 34 /* Number used */ 183 | #define DT_LOOS 0x6000000d /* Start of OS-specific */ 184 | #define DT_HIOS 0x6ffff000 /* End of OS-specific */ 185 | #define DT_VERDEF 0x6ffffffc 186 | #define DT_VERDEFNUM 0x6ffffffd 187 | #define DT_LOPROC 0x70000000 /* Start of processor-specific */ 188 | #define DT_HIPROC 0x7fffffff /* End of processor-specific */ 189 | 190 | 191 | /* Symbol table entry. */ 192 | typedef struct { 193 | Elf32_Word st_name; /* Symbol name (string tbl index) */ 194 | Elf32_Addr st_value; /* Symbol value */ 195 | Elf32_Word st_size; /* Symbol size */ 196 | unsigned char st_info; /* Symbol type and binding */ 197 | unsigned char st_other; /* Symbol visibility */ 198 | Elf32_Section st_shndx; /* Section index */ 199 | } Elf32_Sym; 200 | 201 | typedef struct { 202 | Elf64_Word st_name; /* Symbol name (string tbl index) */ 203 | unsigned char st_info; /* Symbol type and binding */ 204 | unsigned char st_other; /* Symbol visibility */ 205 | Elf64_Section st_shndx; /* Section index */ 206 | Elf64_Addr st_value; /* Symbol value */ 207 | Elf64_Xword st_size; /* Symbol size */ 208 | } Elf64_Sym; 209 | 210 | 211 | #endif 212 | -------------------------------------------------------------------------------- /cbp2ndk/README.md: -------------------------------------------------------------------------------- 1 | 2 | [![Build Travis](https://travis-ci.com/ClnViewer/Code-Blocks-Android-NDK.svg)](https://travis-ci.com/ClnViewer/Code-Blocks-Android-NDK) 3 | 4 | # cbp2ndk 5 | ## Code::Blocks to Android NDK configuration converter 6 | 7 | 8 | Описание работы __cbp2ndk__ [EN](https://clnviewer.github.io/Code-Blocks-Android-NDK/CBP2NDK.EN.html) | [RU](https://clnviewer.github.io/Code-Blocks-Android-NDK/CBP2NDK.RU.html) 9 | Скачать `Code::Blocks` to `Android NDK` [configuration converter](https://clnviewer.github.io/Code-Blocks-Android-NDK/cbp2ndk.zip) v.0.0.14.79 (03.07.2019) 10 | 11 | 12 | ### Параметры командной строки: 13 | 14 | 15 | Options: 16 | -a, --auto find .cbp project file from current directory 17 | -c, --cbp path to .cbp project file 18 | -d, --dump dump current configuration 19 | -t, --tag building tag: Debug|Release|OtherTag 20 | -q, --quiet quiet all messages 21 | -v, --verbose verbose output to console 22 | -n --nodefault no set default values (libs, include paths) 23 | --cbtmpl install C::B wizard template Makefile file 24 | --api android API number (Application.mk) 25 | --abi android ABI platform (Application.mk) 26 | --ndkopt android NDK options (Application.mk) 27 | 28 | Using: 29 | cbp2ndk.exe 30 | cbp2ndk.exe -t -c -v 31 | cbp2ndk.exe -a --api android-28 --abi armeabi-v7a --ndkopt debug 32 | cbp2ndk.exe -a 33 | 34 | 35 | ## License 36 | 37 | _MIT_ 38 | 39 | -------------------------------------------------------------------------------- /cbp2ndk/cbp2ndk.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 92 | 93 | -------------------------------------------------------------------------------- /cbp2ndk/dist/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | project(cbp2ndk) 3 | 4 | file(GLOB_RECURSE sources ../src/*.cpp ../src/*.h ../src/extern/*.h) 5 | file(GLOB_RECURSE data ../src/*.rc) 6 | set(CMAKE_BUILD_TYPE "Release") 7 | 8 | add_executable(cbp2ndk ${sources} ${data}) 9 | target_compile_options(cbp2ndk PUBLIC -std=c++17 -Wall -Wfloat-conversion) 10 | target_include_directories(cbp2ndk PUBLIC ../src ../src/extern) 11 | -------------------------------------------------------------------------------- /cbp2ndk/dist/Test.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 74 | 75 | -------------------------------------------------------------------------------- /cbp2ndk/src/cbp2ndk-CbConf.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 PS 5 | GitHub: https://github.com/ClnViewer/Code-Blocks-Android-NDK 6 | 7 | See https://developer.android.com/ndk/guides/android_mk for more information 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sub license, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | #include "cbp2ndk.h" 29 | #include "extern/argh.h" 30 | 31 | #define __CONF_OPT "", "--ndkopt" 32 | #define __CONF_API "", "--api" 33 | #define __CONF_ABI "", "--abi" 34 | #define __CONF_CBTMPL "", "--cbtmpl" 35 | #define __CONF_TAG "-t", "--tag" 36 | #define __CONF_CBP "-c", "--cbp" 37 | #define __CONF_AUTO "-a", "--auto" 38 | #define __CONF_DUMP "-d", "--dump" 39 | #define __CONF_QUIET "-q", "--quiet" 40 | #define __CONF_VERBOSE "-v", "--verbose" 41 | #define __CONF_NODEFAULT "-n", "--nodefault" 42 | #define __CONF_CBP_EXT ".cbp" 43 | 44 | #if !defined(__OS_IS_WIN) 45 | #define _access access 46 | #endif 47 | 48 | using namespace std; 49 | 50 | CbConf::CbConf(const char **argv, int argc) 51 | : isarg(false), isverb(false), isquiet(false), isdump(false), isnodef(false), 52 | isabi(false), iscbtmpl(false), isapp(false), isand(false), ismkf(false) 53 | { 54 | cmdl(argv, argc); 55 | if (isarg) 56 | path(); 57 | } 58 | 59 | CbConf::~CbConf() {} 60 | 61 | bool CbConf::findcbp() 62 | { 63 | # if defined(__OS_IS_WIN) 64 | bool ret = false; 65 | WIN32_FIND_DATA fd{}; 66 | HANDLE hf; 67 | 68 | if ((hf = ::FindFirstFileA( 69 | static_cast("*" __CONF_CBP_EXT), 70 | &fd) 71 | ) == INVALID_HANDLE_VALUE 72 | ) 73 | return ret; 74 | 75 | do 76 | { 77 | if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 78 | { 79 | if (string_end(fd.cFileName, __CONF_CBP_EXT)) 80 | { 81 | fname[0].assign(fd.cFileName); 82 | ret = true; 83 | break; 84 | } 85 | } 86 | } 87 | while (::FindNextFile(hf, &fd)); 88 | 89 | ::FindClose(hf); 90 | return true; 91 | # else 92 | throw tinyxml2::XmlException("Non-Windows not implemented auto find file.."); 93 | # endif 94 | } 95 | 96 | void CbConf::cmdl(const char **argv, int argc) 97 | { 98 | argh::parser lcmd({ 99 | __CONF_API, 100 | __CONF_ABI, 101 | __CONF_OPT, 102 | __CONF_TAG, 103 | __CONF_CBP, 104 | __CONF_DUMP, 105 | __CONF_AUTO, 106 | __CONF_QUIET, 107 | __CONF_VERBOSE, 108 | __CONF_NODEFAULT 109 | }); 110 | 111 | lcmd.parse(argc, argv); 112 | 113 | bool isauto = (lcmd[{ __CONF_AUTO }]); 114 | bool istag = !(!(lcmd({ __CONF_TAG }) >> tag)); 115 | bool iscnf = !(!(lcmd({ __CONF_CBP }) >> fname[0])); 116 | bool isabi0 = !(!(lcmd({ __CONF_ABI }) >> abi[0])); 117 | bool isabi1 = !(!(lcmd({ __CONF_API }) >> abi[1])); 118 | lcmd({ __CONF_OPT }) >> abi[2]; 119 | iscbtmpl = (lcmd[{ __CONF_CBTMPL }]); 120 | isdump = (lcmd[{ __CONF_DUMP }]); 121 | isquiet = (lcmd[{ __CONF_QUIET }]); 122 | isnodef = (lcmd[{ __CONF_NODEFAULT }]); 123 | isverb = ((isquiet) ? false : (lcmd[{ __CONF_VERBOSE }])); 124 | 125 | if (isauto) 126 | if ((iscnf = findcbp())) 127 | if (tag.empty()) 128 | { 129 | istag = true; 130 | tag = "Release"; 131 | } 132 | 133 | if ((istag) && (iscnf)) 134 | isarg = true; 135 | else if (((!istag) || (!iscnf)) && (lcmd.pos_args().size() >= 3)) 136 | { 137 | if (!istag) 138 | tag = lcmd(1).str(); 139 | if (!iscnf) 140 | fname[0] = lcmd(2).str(); 141 | if (tag.empty()) 142 | return; 143 | if (fname[0].empty()) 144 | if (!findcbp()) 145 | return; 146 | isarg = true; 147 | } 148 | 149 | if ((isabi0) && (isabi1)) 150 | { 151 | isabi = ((!abi[0].empty()) && (!abi[1].empty())); 152 | } 153 | } 154 | 155 | void CbConf::path() 156 | { 157 | if (::_access(fname[0].c_str(), F_OK) < 0) 158 | throw tinyxml2::XmlException("open cbp file: " + fname[0]); 159 | 160 | size_t pos = fname[0].find_last_of("/\\"); 161 | 162 | if (pos == std::string::npos) 163 | { 164 | fname[1] = "Android.mk"; 165 | fname[2] = "Android.mk.tmp"; 166 | fname[3] = "Application.mk"; 167 | fname[4] = "Makefile"; 168 | } 169 | else 170 | { 171 | std::string fpath = fname[0].substr(0,pos); 172 | fname[1] = fpath + __SEPARATOR_PATH "Android.mk"; 173 | fname[2] = fpath + __SEPARATOR_PATH "Android.mk.tmp"; 174 | fname[3] = fpath + __SEPARATOR_PATH "Application.mk"; 175 | fname[4] = fpath + __SEPARATOR_PATH "Makefile"; 176 | } 177 | 178 | if (::_access(fname[4].c_str(), F_OK) < 0) 179 | ismkf = false; 180 | else 181 | ismkf = true; 182 | 183 | if (::_access(fname[3].c_str(), F_OK) < 0) 184 | isapp = false; 185 | else 186 | isapp = true; 187 | 188 | if (::_access(fname[1].c_str(), F_OK) < 0) 189 | isand = false; 190 | else 191 | isand = true; 192 | } 193 | -------------------------------------------------------------------------------- /cbp2ndk/src/cbp2ndk-CbConf.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 PS 5 | GitHub: https://github.com/ClnViewer/Code-Blocks-Android-NDK 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sub license, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | #ifndef __CBCONF_LOCAL_H__ 27 | #define __CBCONF_LOCAL_H__ 28 | 29 | class CbConf 30 | { 31 | private: 32 | void path(); 33 | void cmdl(const char**, int); 34 | bool findcbp(); 35 | 36 | public: 37 | std::vector v[_END_FOR_ARRAY]; 38 | std::map m[2]; 39 | std::string fname[5]; 40 | std::string prjname; 41 | std::string tag; 42 | std::string abi[3]; 43 | /// configuration 44 | bool isarg; 45 | bool isverb; 46 | bool isquiet; 47 | bool isdump; 48 | bool isnodef; 49 | bool isabi; 50 | bool iscbtmpl; 51 | /// files found 52 | bool isapp; 53 | bool isand; 54 | bool ismkf; 55 | 56 | CbConf(const char**, int); 57 | ~CbConf(); 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /cbp2ndk/src/cbp2ndk-cppflags.h: -------------------------------------------------------------------------------- 1 | _TOTXT("-Wabi") 2 | //_TOTXT("-Wabi-tag") 3 | _TOTXT("-Wclass-memaccess") 4 | _TOTXT("-Wctor-dtor-privacy") 5 | _TOTXT("-Wdelete-non-virtual-dtor") 6 | _TOTXT("-Wdeprecated-copy") 7 | //_TOTXT("-Weffc++") ++ match flag 8 | _TOTXT("-Wliteral-suffix") 9 | _TOTXT("-Wlto-type-mismatch") 10 | _TOTXT("-Wmultiple-inheritance") 11 | _TOTXT("-Wnamespaces") 12 | _TOTXT("-Wno-class-conversion") 13 | _TOTXT("-Wno-init-list-lifetime") 14 | _TOTXT("-Wno-narrowing") 15 | _TOTXT("-Wno-non-template-friend") 16 | _TOTXT("-Wno-pessimizing-move") 17 | _TOTXT("-Wno-pmf-conversions") 18 | _TOTXT("-Wno-redundant-move") 19 | _TOTXT("-Wno-terminate") 20 | _TOTXT("-Wnoexcept") 21 | //_TOTXT("-Wnoexcept-type") 22 | _TOTXT("-Wnon-virtual-dtor") 23 | _TOTXT("-Wold-style-cast") 24 | _TOTXT("-Woverloaded-virtual") 25 | _TOTXT("-Wregister") 26 | _TOTXT("-Wreorder") 27 | _TOTXT("-Wsign-promo") 28 | _TOTXT("-Wstrict-null-sentinel") 29 | _TOTXT("-Wtemplates") 30 | _TOTXT("-Wvirtual-inheritance") 31 | _TOTXT("-fabi") /// fake flag 32 | //_TOTXT("-fabi-compat-version") 33 | //_TOTXT("-fabi-version") 34 | _TOTXT("-faligned-new") 35 | _TOTXT("-fchar8_t") 36 | _TOTXT("-fcheck-new") 37 | _TOTXT("-fconcepts") 38 | //_TOTXT("-fconstexpr-depth") 39 | //_TOTXT("-fconstexpr-loop-limit") 40 | //_TOTXT("-fconstexpr-ops-limit") 41 | _TOTXT("-fdeduce-init-list") 42 | _TOTXT("-fext-numeric-literals") 43 | _TOTXT("-fextern-tls-init") 44 | _TOTXT("-fms-extensions") 45 | _TOTXT("-fnew-") /// fake flag 46 | //_TOTXT("-fnew-inheriting-ctors") 47 | //_TOTXT("-fnew-ttp-matching") 48 | _TOTXT("-fno-access-control") 49 | _TOTXT("-fno-char8_t") 50 | _TOTXT("-fno-elide-constructors") 51 | _TOTXT("-fno-enforce-eh-specs") 52 | _TOTXT("-fno-extern-tls-init") 53 | _TOTXT("-fno-gnu-keywords") 54 | _TOTXT("-fno-implement-inlines") 55 | _TOTXT("-fno-implicit-inline-templates") 56 | _TOTXT("-fno-implicit-templates") 57 | _TOTXT("-fno-nonansi-builtins") 58 | _TOTXT("-fno-operator-names") 59 | _TOTXT("-fno-optional-diags") 60 | _TOTXT("-fno-pretty-templates") 61 | _TOTXT("-fno-rtti") 62 | _TOTXT("-fno-threadsafe-statics") 63 | _TOTXT("-fno-use-cxa-get-exception-ptr") 64 | _TOTXT("-fno-weak") 65 | _TOTXT("-fnothrow-opt") 66 | _TOTXT("-fpermissive") 67 | _TOTXT("-frepo") 68 | _TOTXT("-frtti") 69 | _TOTXT("-fsized-deallocation") 70 | _TOTXT("-fstrict-enums") 71 | _TOTXT("-fstrong-eval-order") 72 | _TOTXT("-ftemplate-") /// fake flag 73 | //_TOTXT("-ftemplate-backtrace-limit") 74 | //_TOTXT("-ftemplate-depth") 75 | _TOTXT("-fuse-cxa-atexit") 76 | _TOTXT("-fvisibility-") /// fake flag 77 | //_TOTXT("-fvisibility-inlines-hidden") 78 | //_TOTXT("-fvisibility-ms-compat") 79 | //_TOTXT("-nostdinc++") /// ++ match flag 80 | -------------------------------------------------------------------------------- /cbp2ndk/src/cbp2ndk-dump.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 PS 5 | GitHub: https://github.com/ClnViewer/Code-Blocks-Android-NDK 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sub license, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | #include "cbp2ndk.h" 27 | 28 | using namespace std; 29 | 30 | void dump_CbConf(CbConf *pcnf) 31 | { 32 | try 33 | { 34 | for (auto &val : pcnf->v[elabels::LBL_HINC]) 35 | { 36 | std::cout << " + LBL_HEAD: " << val << std::endl; 37 | } 38 | for (auto &val : pcnf->v[elabels::LBL_CSRC]) 39 | { 40 | std::cout << " + LBL_CSRC: " << val << std::endl; 41 | } 42 | for (auto &val : pcnf->v[elabels::LBL_CFLAG]) 43 | { 44 | std::cout << " + LBL_COMP: " << val << std::endl; 45 | } 46 | for (auto &val : pcnf->v[elabels::LBL_LDFLAG]) 47 | { 48 | std::cout << " + LBL_LDFLAG: " << val << std::endl; 49 | } 50 | for (auto &val : pcnf->v[elabels::LBL_LDLIBS]) 51 | { 52 | std::cout << " + LBL_LDLIBS: " << val << std::endl; 53 | } 54 | for (auto &val : pcnf->v[elabels::LBL_CEXT]) 55 | { 56 | std::cout << " + LBL_CEXT: " << val << std::endl; 57 | } 58 | for (uint32_t i = 0U; i < 5U; i++) 59 | { 60 | std::cout << " + Input files [" << i << "] : "<< pcnf->fname[i] << std::endl; 61 | } 62 | std::cout << " + Project name [title] : "<< pcnf->prjname << std::endl; 63 | std::cout << " i File present [Makefile] : "<< pcnf->ismkf << std::endl; 64 | std::cout << " i File present [Application.mk] : "<< pcnf->isapp << std::endl; 65 | std::cout << " i File present [Android.mk] : "<< pcnf->isand << std::endl; 66 | std::cout << " c Is Dump : "<< pcnf->isdump << std::endl; 67 | std::cout << " c Is Verbose : "<< pcnf->isverb << std::endl; 68 | std::cout << " c Is Quiet : "<< pcnf->isquiet << std::endl; 69 | } 70 | catch (std::exception & _ex) 71 | { 72 | std::cout << " ! Dump : " << _ex.what() << std::endl; 73 | } 74 | 75 | return; 76 | } 77 | -------------------------------------------------------------------------------- /cbp2ndk/src/cbp2ndk-parse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 PS 5 | GitHub: https://github.com/ClnViewer/Code-Blocks-Android-NDK 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sub license, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | #include "cbp2ndk.h" 27 | 28 | using namespace std; 29 | 30 | typedef struct _str_const_cppflag_s 31 | { 32 | const char *str; 33 | const size_t sz; 34 | 35 | } cppflag_s; 36 | 37 | static cppflag_s cppflags[] = 38 | { 39 | #define _TOTXT(A) { A, __CSZ(A) }, 40 | #include "cbp2ndk-cppflags.h" 41 | #undef _TOTXT 42 | }; 43 | 44 | void parse_section( 45 | CbConf *pcnf, 46 | const tinyxml2::XMLDocument & root, 47 | std::string const & sec, 48 | std::string const & attr, 49 | std::function f 50 | ) 51 | { 52 | for (auto unit : tinyxml2::selection( 53 | root, 54 | sec 55 | ) 56 | ) 57 | { 58 | std::string opt = attribute_value(unit, attr); 59 | if (opt.empty()) 60 | continue; 61 | 62 | opt.insert(0, " "); 63 | f(pcnf, opt); 64 | } 65 | } 66 | 67 | void parse_section( 68 | CbConf *pcnf, 69 | const tinyxml2::XMLElement *root, 70 | std::string const & sec, 71 | std::string const & attr, 72 | std::function f 73 | ) 74 | { 75 | for (auto unit : tinyxml2::selection( 76 | root, 77 | sec 78 | ) 79 | ) 80 | { 81 | std::string opt = attribute_value(unit, attr); 82 | if (opt.empty()) 83 | continue; 84 | 85 | opt.insert(0, " "); 86 | f(pcnf, opt); 87 | } 88 | } 89 | 90 | void parse_cflag(CbConf *pcnf, std::string & opt) 91 | { 92 | elabels lb = elabels::LBL_CFLAG; 93 | 94 | do 95 | { 96 | if (string_begin(opt, " -I")) 97 | { 98 | opt.erase(1,2); 99 | lb = elabels::LBL_HINC; 100 | break; 101 | } 102 | if (opt.find('+') != std::string::npos) 103 | { 104 | lb = elabels::LBL_CPPFLAG; 105 | break; 106 | } 107 | for (uint32_t i = 0U; i < __NELE(cppflags); i++) 108 | { 109 | if ((opt.length() - 1) >= cppflags[i].sz) 110 | if (!opt.compare(1U, cppflags[i].sz, cppflags[i].str)) 111 | { 112 | lb = elabels::LBL_CPPFLAG; 113 | break; 114 | } 115 | } 116 | } 117 | while (0); 118 | 119 | pcnf->v[lb].push_back(opt); 120 | } 121 | 122 | void parse_ldflag(CbConf *pcnf, std::string & opt) 123 | { 124 | elabels lb; 125 | 126 | if (string_begin(opt, " -l")) 127 | lb = elabels::LBL_LDLIBS; 128 | else 129 | lb = elabels::LBL_LDFLAG; 130 | 131 | pcnf->v[lb].push_back(opt); 132 | } 133 | 134 | void parse_srclist(CbConf *pcnf, std::string & opt) 135 | { 136 | if ( 137 | (string_end(opt, ".h")) || 138 | (string_end(opt, ".hxx")) || 139 | (string_end(opt, ".hpp")) 140 | ) 141 | { 142 | size_t sp; 143 | if ((sp = opt.find_last_of("/\\")) != std::wstring::npos) 144 | { 145 | std::string incpath = opt.substr(0, sp); 146 | if (!incpath.empty()) 147 | { 148 | if (pcnf->m[1].find(incpath) != pcnf->m[1].end()) 149 | pcnf->m[1].insert(std::make_pair(incpath, 1)); 150 | else 151 | pcnf->m[1][incpath] += 1; 152 | } 153 | } 154 | } 155 | else if ( 156 | (string_end(opt, ".c")) || 157 | (string_end(opt, ".cc")) || 158 | (string_end(opt, ".cxx")) || 159 | (string_end(opt, ".cpp")) 160 | ) 161 | { 162 | if (!string_end(opt, ".c")) 163 | { 164 | size_t sp; 165 | if ((sp = opt.find_last_of(".")) != std::wstring::npos) 166 | { 167 | std::string ext = opt.substr(sp, opt.length() - sp); 168 | if (!ext.empty()) 169 | { 170 | if (pcnf->m[0].find(ext) != pcnf->m[0].end()) 171 | pcnf->m[0].insert(std::make_pair(ext, 1)); 172 | else 173 | pcnf->m[0][ext] += 1; 174 | } 175 | } 176 | } 177 | pcnf->v[elabels::LBL_CSRC].push_back(opt); 178 | } 179 | else 180 | if (pcnf->isverb) 181 | std::cout << " ! Skip: not support file extension: " << opt.c_str() << std::endl; 182 | } 183 | 184 | void parse_prjname(CbConf *pcnf, std::string & opt) 185 | { 186 | static const char rchars[] = "!@#$%^&*()+- ?><'\""; 187 | string_trim(opt); 188 | 189 | for (uint32_t i = 0U; i < __CSZ(rchars); i++) 190 | { 191 | while (opt.find(rchars[i]) != string::npos) 192 | opt.replace(opt.find(rchars[i]), 1, "_"); 193 | } 194 | pcnf->prjname.assign(opt); 195 | } 196 | -------------------------------------------------------------------------------- /cbp2ndk/src/cbp2ndk-write.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 PS 5 | GitHub: https://github.com/ClnViewer/Code-Blocks-Android-NDK 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sub license, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | #include "cbp2ndk.h" 27 | 28 | using namespace std; 29 | 30 | static const char android_default_begin[] = 31 | "LOCAL_PATH := $(call my-dir)\n" \ 32 | "include $(CLEAR_VARS)\n"; 33 | 34 | static const char android_default_end[] = 35 | "LOCAL_SRC_FILES :=\n" \ 36 | "include $(BUILD_EXECUTABLE)\n"; 37 | 38 | static inline const char *labels_andoid_mk[] = 39 | { 40 | static_cast("LOCAL_CPP_EXTENSION :="), 41 | static_cast("LOCAL_SRC_FILES :="), 42 | static_cast("LOCAL_CFLAGS :="), 43 | static_cast("LOCAL_CPPFLAGS :="), 44 | static_cast("LOCAL_LDFLAGS :="), 45 | static_cast("LOCAL_LDLIBS :="), 46 | static_cast("LOCAL_C_INCLUDES :="), 47 | static_cast("CBP2NDK_CMDLINE :="), 48 | static_cast("LOCAL_MODULE :="), 49 | static_cast("\n") 50 | }; 51 | 52 | static inline const char *labels_app_mk[] = 53 | { 54 | static_cast("APP_BUILD_SCRIPT := "), 55 | static_cast("APP_STL := "), 56 | static_cast("APP_ABI := "), 57 | static_cast("APP_PLATFORM := "), 58 | static_cast("APP_OPTIM := ") 59 | }; 60 | 61 | static inline const char *data_app_mk[] = 62 | { 63 | static_cast("Android.mk"), 64 | static_cast("c++_static") 65 | }; 66 | 67 | static const LPCSTR resdata[] = 68 | { 69 | static_cast("APPDATA"), 70 | static_cast("MKFDATA"), 71 | static_cast("MKFDATACBTEMPLATE"), 72 | }; 73 | 74 | enum eresdata 75 | { 76 | RES_APPDATA = 0, 77 | RES_MKFDATA, 78 | RES_MKFDATACB 79 | }; 80 | 81 | enum efname 82 | { 83 | PATH_CBP = 0, 84 | PATH_MK, 85 | PATH_MKTMP, 86 | PATH_APP, 87 | PATH_MAKE 88 | }; 89 | 90 | PBYTE get_resource(LPCSTR sid, size_t *sz) 91 | { 92 | # if defined(__OS_IS_WIN) 93 | do 94 | { 95 | HMODULE hm; 96 | HRSRC hres; 97 | HGLOBAL hmem; 98 | PBYTE data; 99 | 100 | *sz = 0U; 101 | 102 | if ((hm = GetModuleHandleA(NULL)) == INVALID_HANDLE_VALUE) 103 | break; 104 | if (!(hres = FindResourceA(hm, sid, RT_RCDATA))) 105 | break; 106 | if (!(hmem = LoadResource(hm, hres))) 107 | break; 108 | if (!(*sz = SizeofResource(hm, hres))) 109 | break; 110 | if (!(data = static_cast(LockResource(hmem)))) 111 | break; 112 | 113 | return data; 114 | } 115 | while (0); 116 | 117 | return nullptr; 118 | # else 119 | throw tinyxml2::XmlException("Non-Windows not implemented build in resource.."); 120 | # endif 121 | } 122 | 123 | const char * get_label(int32_t idx) 124 | { 125 | if ((idx < 0) || (idx >= static_cast(__NELE(labels_andoid_mk)))) 126 | return labels_andoid_mk[(__NELE(labels_andoid_mk) - 1)]; 127 | return labels_andoid_mk[idx]; 128 | } 129 | 130 | bool if_section(CbConf *pcnf, int32_t idx) 131 | { 132 | return (pcnf->v[idx].size()); 133 | } 134 | 135 | bool write_label(FILE *fp, int32_t idx, bool isnl) 136 | { 137 | size_t sz = strlen(get_label(idx)); 138 | if (fwrite(get_label(idx), 1, sz, fp) != sz) 139 | return false; 140 | 141 | if (isnl) 142 | fputc('\n', fp); 143 | 144 | return true; 145 | } 146 | 147 | bool write_section(FILE *fp, CbConf *pcnf, int32_t idx) 148 | { 149 | for (auto &val : pcnf->v[idx]) 150 | { 151 | # if defined(_DEBUG) 152 | if (pcnf->isverb) 153 | std::cout << "\t+ : " << val << std::endl; 154 | # endif 155 | if (fwrite(val.data(), 1, val.length(), fp) != val.length()) 156 | return false; 157 | } 158 | 159 | size_t sz = strlen(get_label(elabels::LBL_END)); 160 | if (fwrite(get_label(elabels::LBL_END), 1, sz, fp) != sz) 161 | return false; 162 | 163 | return true; 164 | } 165 | 166 | static void write_data(CbConf *pcnf, LPCSTR sid, int32_t fid) 167 | { 168 | FILE __AUTO(__autofile) *fp = NULL; 169 | 170 | if (!(fp = fopen(pcnf->fname[fid].c_str(), "wt"))) 171 | throw tinyxml2::XmlException("open file to write"); 172 | 173 | # if defined(_DEBUG) 174 | if (pcnf->isverb) 175 | std::cout << " * Create (default): " << pcnf->fname[fid].c_str() << std::endl; 176 | # endif 177 | 178 | do 179 | { 180 | PBYTE data; 181 | size_t sz; 182 | 183 | if ( 184 | (!(data = get_resource(sid, &sz))) || 185 | (!sz) 186 | ) 187 | break; 188 | 189 | fwrite(data, 1, sz, fp); 190 | fclose(fp); fp = NULL; 191 | 192 | return; 193 | } 194 | while (0); 195 | 196 | throw tinyxml2::XmlException("get/set resource"); 197 | } 198 | 199 | void write_andmk(CbConf *pcnf) 200 | { 201 | FILE __AUTO(__autofile) *fp = NULL; 202 | 203 | if (!(fp = fopen(pcnf->fname[1].c_str(), "wt"))) 204 | throw tinyxml2::XmlException("open file Android.mk to write"); 205 | 206 | # if defined(_DEBUG) 207 | if (pcnf->isverb) 208 | std::cout << " * Create (default): " << pcnf->fname[1].c_str() << std::endl; 209 | # endif 210 | 211 | std::string nmodule(get_label(elabels::LBL_NAME)); 212 | nmodule.append(" " + pcnf->prjname + "\n"); 213 | 214 | fwrite(android_default_begin, 1, __CSZ(android_default_begin), fp); 215 | fwrite(nmodule.data(), 1, nmodule.length(), fp); 216 | fwrite(android_default_end, 1, __CSZ(android_default_end), fp); 217 | fclose(fp); fp = NULL; 218 | } 219 | 220 | void write_makef(CbConf *pcnf) 221 | { 222 | write_data(pcnf, resdata[eresdata::RES_MKFDATA], efname::PATH_MAKE); 223 | if (!pcnf->isquiet) 224 | std::cout << " ? Warning : New Makefile - \n\t You need to edit the NDKROOT variable, specifying the path to the Android NDK on your system." << std::endl; 225 | } 226 | 227 | void write_makefcb(CbConf *pcnf) 228 | { 229 | write_data(pcnf, resdata[eresdata::RES_MKFDATACB], efname::PATH_MAKE); 230 | } 231 | 232 | void write_appmk(CbConf *pcnf) 233 | { 234 | write_data(pcnf, resdata[eresdata::RES_APPDATA], efname::PATH_APP); 235 | } 236 | 237 | void write_appmk_custom(CbConf *pcnf) 238 | { 239 | if (!pcnf->isabi) 240 | return; 241 | 242 | FILE __AUTO(__autofile) *fp = NULL; 243 | if (!(fp = fopen(pcnf->fname[efname::PATH_APP].c_str(), "wt"))) 244 | throw tinyxml2::XmlException("open file to write"); 245 | 246 | std::stringstream ss; 247 | 248 | for (uint32_t i = 0U; i < __NELE(labels_app_mk); i++) 249 | { 250 | ss << labels_app_mk[i]; 251 | 252 | switch (i) 253 | { 254 | case 0: 255 | case 1: 256 | { 257 | ss << data_app_mk[i]; 258 | break; 259 | } 260 | case 2: 261 | case 3: 262 | case 4: 263 | { 264 | uint32_t idx = (i - 2U); 265 | if (!pcnf->abi[idx].empty()) 266 | ss << pcnf->abi[idx].c_str(); 267 | break; 268 | } 269 | } 270 | ss << "\n"; 271 | } 272 | fwrite(ss.str().data(), 1, ss.str().length(), fp); 273 | } 274 | -------------------------------------------------------------------------------- /cbp2ndk/src/cbp2ndk.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 PS 5 | GitHub: https://github.com/ClnViewer/Code-Blocks-Android-NDK 6 | 7 | See https://developer.android.com/ndk/guides/android_mk for more information 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sub license, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | #include "cbp2ndk.h" 29 | 30 | using namespace std; 31 | 32 | int main(int argc, const char *argv[]) 33 | { 34 | CbConf cnf(argv, argc); 35 | 36 | if (!cnf.isarg) 37 | { 38 | const char *exebin = strrchr(argv[0], '\\'); 39 | exebin = ((exebin) ? (exebin + 1) : argv[0]); 40 | 41 | std::cout << std::endl << " Code::Blocks to Android NDK configuration converter v." << CBP_FULLVERSION_STRING << " (" << CBP_DATE << "." << CBP_MONTH << "." << CBP_YEAR << ")" << std::endl; 42 | std::cout << " C::B to NDK HOWTO: https://clnviewer.github.io/Code-Blocks-Android-NDK/" << std::endl; 43 | std::cout << " Android.mk HOWTO: https://developer.android.com/ndk/guides/android_mk" << std::endl << std::endl; 44 | std::cout << " Options: " << std::endl; 45 | std::cout << "\t-a, --auto\tfind .cbp project file from current directory" << std::endl; 46 | std::cout << "\t-c, --cbp\tpath to .cbp project file" << std::endl; 47 | std::cout << "\t-d, --dump\tdump current configuration" << std::endl; 48 | std::cout << "\t-t, --tag\tbuilding tag: Debug|Release|OtherTag" << std::endl; 49 | std::cout << "\t-q, --quiet\tquiet all messages" << std::endl; 50 | std::cout << "\t-v, --verbose\tverbose output to console" << std::endl; 51 | std::cout << "\t-n --nodefault\tno set default values" << std::endl; 52 | std::cout << "\t --cbtmpl\tinstall C::B wizard template Makefile" << std::endl; 53 | std::cout << "\t --api\tandroid API number (Application.mk)" << std::endl; 54 | std::cout << "\t --abi\tandroid ABI platform (Application.mk)" << std::endl; 55 | std::cout << "\t --ndkopt\tandroid NDK options (Application.mk)" << std::endl << std::endl; 56 | std::cout << " Using: " << std::endl; 57 | std::cout << "\t" << exebin << " " << std::endl; 58 | std::cout << "\t" << exebin << " -t -c -v" << std::endl; 59 | std::cout << "\t" << exebin << " -a --api android-28 --abi armeabi-v7a --ndkopt debug" << std::endl; 60 | std::cout << "\t" << exebin << " -a" << std::endl; 61 | return 127; 62 | } 63 | 64 | try 65 | { 66 | auto doc = tinyxml2::load_xmlfile(cnf.fname[0]); 67 | 68 | if (cnf.isverb) 69 | std::cout << " * Open (xml): " << cnf.fname[0].c_str() << std::endl; 70 | 71 | /// begin XML configuration parse 72 | 73 | if ((!cnf.ismkf) && (cnf.iscbtmpl)) 74 | write_makefcb(&cnf); 75 | else if (!cnf.ismkf) 76 | write_makef(&cnf); 77 | 78 | if ((!cnf.isapp) && (!cnf.isabi)) 79 | write_appmk(&cnf); 80 | else if (cnf.isabi) 81 | write_appmk_custom(&cnf); 82 | 83 | if (!cnf.isand) 84 | { 85 | parse_section( 86 | &cnf, 87 | static_cast(*doc), 88 | "CodeBlocks_project_file/Project/Option"s, 89 | "title"s, 90 | [](CbConf *pcnf, std::string & opt) 91 | { 92 | parse_prjname(pcnf, opt); 93 | } 94 | ); 95 | 96 | if (cnf.prjname.empty()) 97 | throw tinyxml2::XmlException("no project name in cbp configuration"); 98 | 99 | write_andmk(&cnf); 100 | } 101 | 102 | parse_section( 103 | &cnf, 104 | static_cast(*doc), 105 | "CodeBlocks_project_file/Project/Unit"s, 106 | "filename"s, 107 | [](CbConf *pcnf, std::string & opt) 108 | { 109 | parse_srclist(pcnf, opt); 110 | } 111 | ); 112 | for (auto root : 113 | tinyxml2::selection( 114 | static_cast(*doc), 115 | "CodeBlocks_project_file/Project/Build/Target" 116 | ) 117 | ) { 118 | std::string taged = attribute_value(root, "title"); 119 | if ( 120 | (taged.empty()) || 121 | (!string_end(cnf.tag, taged)) 122 | ) 123 | continue; 124 | 125 | parse_section( 126 | &cnf, 127 | root, 128 | "Compiler/Add"s, 129 | "option"s, 130 | [](CbConf *pcnf, std::string & opt) 131 | { 132 | parse_cflag(pcnf, opt); 133 | } 134 | ); 135 | parse_section( 136 | &cnf, 137 | root, 138 | "Linker/Add"s, 139 | "option"s, 140 | [](CbConf *pcnf, std::string & opt) 141 | { 142 | parse_ldflag(pcnf, opt); 143 | } 144 | ); 145 | parse_section( 146 | &cnf, 147 | root, 148 | "Option"s, 149 | "parameters"s, 150 | [](CbConf *pcnf, std::string & opt) 151 | { 152 | pcnf->v[elabels::LBL_CMDL].push_back(opt); 153 | } 154 | ); 155 | } 156 | for (auto root : 157 | tinyxml2::selection( 158 | static_cast(*doc), 159 | "CodeBlocks_project_file/Project" 160 | ) 161 | ) { 162 | parse_section( 163 | &cnf, 164 | root, 165 | "Compiler/Add"s, 166 | "option"s, 167 | [](CbConf *pcnf, std::string & opt) 168 | { 169 | parse_cflag(pcnf, opt); 170 | } 171 | ); 172 | parse_section( 173 | &cnf, 174 | root, 175 | "Linker/Add"s, 176 | "option"s, 177 | [](CbConf *pcnf, std::string & opt) 178 | { 179 | parse_ldflag(pcnf, opt); 180 | } 181 | ); 182 | } 183 | 184 | /// append default values 185 | if (!cnf.isnodef) 186 | { 187 | cnf.v[elabels::LBL_LDLIBS].push_back(" -llog"); 188 | cnf.v[elabels::LBL_CFLAG].push_back(" -D__ANDROID_API_PLATFORM__=\"$(TARGET_PLATFORM)\""); 189 | cnf.v[elabels::LBL_HINC].push_back(" ./"); 190 | } 191 | 192 | /// map to values 193 | std::map::iterator mit0 = cnf.m[0].begin(); 194 | while(mit0 != cnf.m[0].end()) 195 | { 196 | std::string opt = mit0->first; 197 | if (opt.empty()) 198 | continue; 199 | 200 | opt.insert(0, " "); 201 | cnf.v[elabels::LBL_CEXT].push_back(opt); 202 | mit0++; 203 | } 204 | 205 | std::map::iterator mit1 = cnf.m[1].begin(); 206 | while(mit1 != cnf.m[1].end()) 207 | { 208 | std::string opt = mit1->first; 209 | if (opt.empty()) 210 | continue; 211 | 212 | opt.insert(0, " "); 213 | cnf.v[elabels::LBL_HINC].push_back(opt); 214 | mit1++; 215 | } 216 | 217 | if (cnf.isdump) 218 | dump_CbConf(&cnf); 219 | 220 | /// end XML configuration parse 221 | 222 | FILE __AUTO(__autofile) *fpi = NULL; 223 | FILE __AUTO(__autofile) *fpo = NULL; 224 | 225 | if (!(fpi = fopen(cnf.fname[1].c_str(), "rt"))) 226 | throw tinyxml2::XmlException("open file Android.mk to write"); 227 | 228 | if (cnf.isverb) 229 | std::cout << " * Open (r): " << cnf.fname[1].c_str() << std::endl; 230 | 231 | ::fseek(fpi, 0L, SEEK_END); 232 | size_t sz = static_cast(::ftell(fpi)); 233 | if (!sz) 234 | { 235 | fclose(fpi); fpi = NULL; 236 | (void) remove(cnf.fname[1].c_str()); 237 | throw tinyxml2::XmlException("file Android.mk is empty, deleted, re-run it.."); 238 | } 239 | 240 | ::fseek(fpi, 0L, SEEK_SET); 241 | 242 | if (!(fpo = fopen(cnf.fname[2].c_str(), "wt"))) 243 | throw tinyxml2::XmlException("open file Android.mk.tmp to write"); 244 | 245 | if (cnf.isverb) 246 | std::cout << " * Open (w): " << cnf.fname[2].c_str() << std::endl; 247 | 248 | bool iswrite = false; 249 | char *buf = new char[sz]{}; 250 | 251 | while(fgets(buf, sz, fpi)) 252 | { 253 | bool isskip = false; 254 | for (int n = elabels::LBL_CEXT; n < _END_FOR_ARRAY; n++) 255 | { 256 | size_t sp; 257 | std::string needle(get_label(n)); 258 | 259 | if ((sp = needle.find(" ")) != std::wstring::npos) 260 | { 261 | needle = needle.substr(0, sp - 1); 262 | if (!needle.empty()) 263 | { 264 | if (string_begin(buf, needle)) 265 | { 266 | isskip = true; 267 | break; 268 | } 269 | } 270 | } 271 | } 272 | if (isskip) 273 | { 274 | if (!iswrite) 275 | { 276 | for (int i = elabels::LBL_CEXT; i < _END_FOR_ARRAY; i++) 277 | { 278 | if (if_section(&cnf, i)) 279 | { 280 | if (!write_label(fpo, i, false)) 281 | break; 282 | if (!write_section(fpo, &cnf, i)) 283 | break; 284 | } 285 | } 286 | if (!if_section(&cnf, elabels::LBL_CMDL)) 287 | (void) write_label(fpo, elabels::LBL_CMDL, true); 288 | iswrite = true; 289 | } 290 | continue; 291 | } 292 | fwrite(buf, 1, strlen(buf), fpo); 293 | } 294 | delete [] buf; 295 | 296 | fclose(fpi); fpi = NULL; 297 | fclose(fpo); fpo = NULL; 298 | 299 | if (remove(cnf.fname[1].c_str())) 300 | throw tinyxml2::XmlException("remove old file Android.mk"); 301 | if (rename(cnf.fname[2].c_str(), cnf.fname[1].c_str())) 302 | throw tinyxml2::XmlException("move new file Android.mk"); 303 | 304 | if (!cnf.isquiet) 305 | std::cout << " * C::B -> Android NDK - convertible configuration done." << std::endl; 306 | } 307 | catch (tinyxml2::XmlException & _ex) 308 | { 309 | if (!cnf.isquiet) 310 | std::cout << " ! Error : " << _ex.what() << std::endl; 311 | return 125; 312 | } 313 | catch (std::exception & _ex) 314 | { 315 | if (!cnf.isquiet) 316 | std::cout << " ! Exception : " << _ex.what() << std::endl; 317 | return 126; 318 | } 319 | 320 | return 0; 321 | } 322 | -------------------------------------------------------------------------------- /cbp2ndk/src/cbp2ndk.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 PS 5 | GitHub: https://github.com/ClnViewer/Code-Blocks-Android-NDK 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sub license, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | #ifndef __CBP2NDK_LOCAL_H__ 27 | #define __CBP2NDK_LOCAL_H__ 28 | 29 | #if !defined(_WIN32_WINNT) 30 | # define _WIN32_WINNT 0x0501 31 | #endif 32 | 33 | #if (defined(_WIN32) || defined(__WIN32__) || \ 34 | defined(_WIN64) || defined(__WIN64__) || \ 35 | defined(__WINNT) || defined(__WINNT__) || defined(WINNT) || \ 36 | defined(_Windows) || defined(_MSC_VER) || \ 37 | defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)) 38 | # define __OS_IS_WIN 1 39 | # define __SEPARATOR_PATH "\\" 40 | #else 41 | # define __SEPARATOR_PATH "/" 42 | #endif 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include "extern/tixml2ex.h" 51 | #include "../version.h" 52 | #include 53 | #include 54 | #include 55 | 56 | #define __CSZ(a) static_cast(sizeof(a)-1) 57 | #define __NELE(a) (sizeof(a) / sizeof(a[0])) 58 | #define __AUTO(x) __attribute__((cleanup(x))) 59 | 60 | static inline void __attribute__((always_inline)) __autofree(void *v) 61 | { 62 | if (v) 63 | { 64 | # if defined(__cplusplus) 65 | void *x = static_cast(*static_cast(v)); 66 | # else 67 | void *x = (void*)(*(void**)v); 68 | # endif 69 | if (x) 70 | { 71 | free(x); 72 | } 73 | } 74 | } 75 | 76 | static inline void __attribute__((always_inline)) __autofile(void *v) 77 | { 78 | if (v) 79 | { 80 | # if defined(__cplusplus) 81 | void *x = static_cast(*static_cast(v)); 82 | # else 83 | void *x = (void*)(*(void**)v); 84 | # endif 85 | if (x) 86 | { 87 | # if defined(__cplusplus) 88 | fclose(static_cast(x)); 89 | # else 90 | fclose((FILE*)x); 91 | # endif 92 | x = NULL; 93 | } 94 | } 95 | } 96 | 97 | #if defined(__cplusplus) 98 | 99 | inline bool string_end(std::string const & val, std::string const & ending) 100 | { 101 | if (ending.size() > val.size()) return false; 102 | return std::equal(ending.rbegin(), ending.rend(), val.rbegin()); 103 | } 104 | 105 | inline bool string_begin(std::string const & val, std::string const & start) 106 | { 107 | if (start.size() > val.size()) return false; 108 | return std::equal(start.begin(), start.end(), val.begin()); 109 | } 110 | 111 | inline void string_trim(std::string & str) 112 | { 113 | str.erase(0, str.find_first_not_of(' ')); 114 | str.erase(str.find_last_not_of(' ')+1); 115 | } 116 | 117 | #endif 118 | 119 | enum elabels 120 | { 121 | LBL_CEXT, 122 | LBL_CSRC, 123 | LBL_CFLAG, 124 | LBL_CPPFLAG, 125 | LBL_LDFLAG, 126 | LBL_LDLIBS, 127 | LBL_HINC, 128 | LBL_CMDL, 129 | LBL_NAME, 130 | LBL_END 131 | }; 132 | 133 | #define _END_FOR_ARRAY elabels::LBL_NAME 134 | #include "cbp2ndk-CbConf.h" 135 | 136 | const char * get_label(int32_t); 137 | PBYTE get_resource(LPCSTR, size_t*); 138 | 139 | void dump_CbConf(CbConf*); 140 | bool if_section(CbConf*, int32_t); 141 | bool write_label(FILE*, int32_t, bool); 142 | bool write_section(FILE*, CbConf*, int32_t); 143 | void write_appmk_custom(CbConf*); 144 | void write_appmk(CbConf*); 145 | void write_andmk(CbConf*); 146 | void write_makef(CbConf*); 147 | void write_makefcb(CbConf*); 148 | 149 | void parse_cflag( 150 | CbConf*, 151 | std::string&); 152 | 153 | void parse_ldflag( 154 | CbConf*, 155 | std::string&); 156 | 157 | void parse_srclist( 158 | CbConf*, 159 | std::string&); 160 | 161 | void parse_prjname( 162 | CbConf*, 163 | std::string&); 164 | 165 | void parse_section( 166 | CbConf*, 167 | const tinyxml2::XMLDocument&, 168 | std::string const&, 169 | std::string const&, 170 | std::function); 171 | 172 | void parse_section( 173 | CbConf*, 174 | const tinyxml2::XMLElement*, 175 | std::string const&, 176 | std::string const&, 177 | std::function); 178 | 179 | #endif 180 | -------------------------------------------------------------------------------- /cbp2ndk/src/cbp2ndk.rc: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2018 PS 5 | GitHub: https://github.com/ClnViewer/Code-Blocks-Android-NDK 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sub license, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | #include "../version.h" 26 | #define _TOSTR(a) #a 27 | #define __TOSTR(a) _TOSTR(a) 28 | 29 | 30 | MKFDATA RCDATA "../../CB-Template/Makefile" 31 | APPDATA RCDATA "../../CB-Template/Application.mk" 32 | MKFDATACBTEMPLATE RCDATA "../../CB-Template/autoinstall/src/CodeBlocks/templates/wizard/ndk_android/files/Makefile" 33 | 34 | LANGUAGE 0x19, 0x01 35 | 1 VERSIONINFO 36 | FILEVERSION CBP_RC_FILEVERSION 37 | PRODUCTVERSION CBP_RC_FILEVERSION 38 | FILEOS 0x4 39 | FILETYPE 0x2 40 | FILESUBTYPE 0x0 41 | FILEFLAGSMASK 0x2 42 | FILEFLAGS 0x2 43 | { 44 | BLOCK "StringFileInfo" 45 | { 46 | BLOCK "040904b0" 47 | { 48 | VALUE "CompanyName", "PS https://clnviewer.github.io/Code-Blocks-Android-NDK/" 49 | VALUE "FileDescription", "Code::Blocks to Android NDK configuration converter" 50 | VALUE "FileVersion", CBP_FULLVERSION_STRING 51 | VALUE "InternalName", "cbp2ndk" 52 | VALUE "LegalCopyright", "Copyright PS 2016-2019. This is freeware." 53 | VALUE "ProductName", "cbp2ndk (" __TOSTR(CBP_REVISION) ") [" __TOSTR(CBP_BUILDS_COUNT) "][" __TOSTR(CBP_BUILD_HISTORY) "]" 54 | VALUE "OriginalFilename", "cbp2ndk.exe" 55 | VALUE "ProductVersion", CBP_FULLVERSION_STRING 56 | VALUE "CompanyShortName", "PS" 57 | VALUE "ProductShortName", "cbp2ndk" 58 | VALUE "LastChange", CBP_YEAR " " CBP_MONTH " " CBP_DATE 59 | VALUE "Official Build", "0" 60 | } 61 | } 62 | 63 | BLOCK "VarFileInfo" 64 | { 65 | VALUE "Translation", 0x0419, 1251 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /cbp2ndk/src/extern/argh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace argh 12 | { 13 | // Terminology: 14 | // A command line is composed of 2 types of args: 15 | // 1. Positional args, i.e. free standing values 16 | // 2. Options: args beginning with '-'. We identify two kinds: 17 | // 2.1: Flags: boolean options => (exist ? true : false) 18 | // 2.2: Parameters: a name followed by a non-option value 19 | 20 | #if !defined(__GNUC__) || (__GNUC__ >= 5) 21 | using string_stream = std::istringstream; 22 | #else 23 | // Until GCC 5, istringstream did not have a move constructor. 24 | // stringstream_proxy is used instead, as a workaround. 25 | class stringstream_proxy 26 | { 27 | public: 28 | stringstream_proxy() = default; 29 | 30 | // Construct with a value. 31 | stringstream_proxy(std::string const& value) : 32 | stream_(value) 33 | {} 34 | 35 | // Copy constructor. 36 | stringstream_proxy(const stringstream_proxy& other) : 37 | stream_(other.stream_.str()) 38 | { 39 | stream_.setstate(other.stream_.rdstate()); 40 | } 41 | 42 | void setstate(std::ios_base::iostate state) { stream_.setstate(state); } 43 | 44 | // Stream out the value of the parameter. 45 | // If the conversion was not possible, the stream will enter the fail state, 46 | // and operator bool will return false. 47 | template 48 | stringstream_proxy& operator >> (T& thing) 49 | { 50 | stream_ >> thing; 51 | return *this; 52 | } 53 | 54 | 55 | // Get the string value. 56 | std::string str() const { return stream_.str(); } 57 | 58 | std::stringbuf* rdbuf() const { return stream_.rdbuf(); } 59 | 60 | // Check the state of the stream. 61 | // False when the most recent stream operation failed 62 | operator bool() const { return !!stream_; } 63 | 64 | ~stringstream_proxy() = default; 65 | private: 66 | std::istringstream stream_; 67 | }; 68 | using string_stream = stringstream_proxy; 69 | #endif 70 | 71 | class parser 72 | { 73 | public: 74 | enum Mode { PREFER_FLAG_FOR_UNREG_OPTION = 1 << 0, 75 | PREFER_PARAM_FOR_UNREG_OPTION = 1 << 1, 76 | NO_SPLIT_ON_EQUALSIGN = 1 << 2, 77 | SINGLE_DASH_IS_MULTIFLAG = 1 << 3, 78 | }; 79 | 80 | parser() = default; 81 | 82 | parser(std::initializer_list pre_reg_names) 83 | { add_params(pre_reg_names); } 84 | 85 | parser(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION) 86 | { parse(argv, mode); } 87 | 88 | parser(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION) 89 | { parse(argc, argv, mode); } 90 | 91 | void add_param(std::string const& name); 92 | void add_params(std::initializer_list init_list); 93 | 94 | void parse(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION); 95 | void parse(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION); 96 | 97 | std::multiset const& flags() const { return flags_; } 98 | std::map const& params() const { return params_; } 99 | std::vector const& pos_args() const { return pos_args_; } 100 | 101 | // begin() and end() for using range-for over positional args. 102 | std::vector::const_iterator begin() const { return pos_args_.cbegin(); } 103 | std::vector::const_iterator end() const { return pos_args_.cend(); } 104 | size_t size() const { return pos_args_.size(); } 105 | 106 | ////////////////////////////////////////////////////////////////////////// 107 | // Accessors 108 | 109 | // flag (boolean) accessors: return true if the flag appeared, otherwise false. 110 | bool operator[](std::string const& name) const; 111 | 112 | // multiple flag (boolean) accessors: return true if at least one of the flag appeared, otherwise false. 113 | bool operator[](std::initializer_list init_list) const; 114 | 115 | // returns positional arg string by order. Like argv[] but without the options 116 | std::string const& operator[](size_t ind) const; 117 | 118 | // returns a std::istream that can be used to convert a positional arg to a typed value. 119 | string_stream operator()(size_t ind) const; 120 | 121 | // same as above, but with a default value in case the arg is missing (index out of range). 122 | template 123 | string_stream operator()(size_t ind, T&& def_val) const; 124 | 125 | // parameter accessors, give a name get an std::istream that can be used to convert to a typed value. 126 | // call .str() on result to get as string 127 | string_stream operator()(std::string const& name) const; 128 | 129 | // accessor for a parameter with multiple names, give a list of names, get an std::istream that can be used to convert to a typed value. 130 | // call .str() on result to get as string 131 | // returns the first value in the list to be found. 132 | string_stream operator()(std::initializer_list init_list) const; 133 | 134 | // same as above, but with a default value in case the param was missing. 135 | // Non-string def_val types must have an operator<<() (output stream operator) 136 | // If T only has an input stream operator, pass the string version of the type as in "3" instead of 3. 137 | template 138 | string_stream operator()(std::string const& name, T&& def_val) const; 139 | 140 | // same as above but for a list of names. returns the first value to be found. 141 | template 142 | string_stream operator()(std::initializer_list init_list, T&& def_val) const; 143 | 144 | private: 145 | string_stream bad_stream() const; 146 | std::string trim_leading_dashes(std::string const& name) const; 147 | bool is_number(std::string const& arg) const; 148 | bool is_option(std::string const& arg) const; 149 | bool got_flag(std::string const& name) const; 150 | bool is_param(std::string const& name) const; 151 | 152 | private: 153 | std::vector args_; 154 | std::map params_; 155 | std::vector pos_args_; 156 | std::multiset flags_; 157 | std::set registeredParams_; 158 | std::string empty_; 159 | }; 160 | 161 | 162 | ////////////////////////////////////////////////////////////////////////// 163 | 164 | inline void parser::parse(const char * const argv[], int mode) 165 | { 166 | int argc = 0; 167 | for (auto argvp = argv; *argvp; ++argc, ++argvp); 168 | parse(argc, argv, mode); 169 | } 170 | 171 | ////////////////////////////////////////////////////////////////////////// 172 | 173 | inline void parser::parse(int argc, const char* const argv[], int mode /*= PREFER_FLAG_FOR_UNREG_OPTION*/) 174 | { 175 | // convert to strings 176 | args_.resize(argc); 177 | std::transform(argv, argv + argc, args_.begin(), [](const char* const arg) { return arg; }); 178 | 179 | // parse line 180 | for (auto i = 0u; i < args_.size(); ++i) 181 | { 182 | if (!is_option(args_[i])) 183 | { 184 | pos_args_.emplace_back(args_[i]); 185 | continue; 186 | } 187 | 188 | auto name = trim_leading_dashes(args_[i]); 189 | 190 | if (!(mode & NO_SPLIT_ON_EQUALSIGN)) 191 | { 192 | auto equalPos = name.find('='); 193 | if (equalPos != std::string::npos) 194 | { 195 | params_.insert({ name.substr(0, equalPos), name.substr(equalPos + 1) }); 196 | continue; 197 | } 198 | } 199 | 200 | // if the option is unregistered and should be a multi-flag 201 | if (1 == (args_[i].size() - name.size()) && // single dash 202 | argh::parser::SINGLE_DASH_IS_MULTIFLAG & mode && // multi-flag mode 203 | !is_param(name)) // unregistered 204 | { 205 | std::string keep_param; 206 | 207 | if (!name.empty() && is_param(std::string(1ul, name.back()))) // last char is param 208 | { 209 | keep_param += name.back(); 210 | name.resize(name.size() - 1); 211 | } 212 | 213 | for (auto const& c : name) 214 | { 215 | flags_.emplace(std::string{ c }); 216 | } 217 | 218 | if (!keep_param.empty()) 219 | { 220 | name = keep_param; 221 | } 222 | else 223 | { 224 | continue; // do not consider other options for this arg 225 | } 226 | } 227 | 228 | // any potential option will get as its value the next arg, unless that arg is an option too 229 | // in that case it will be determined a flag. 230 | if (i == args_.size() - 1 || is_option(args_[i + 1])) 231 | { 232 | flags_.emplace(name); 233 | continue; 234 | } 235 | 236 | // if 'name' is a pre-registered option, then the next arg cannot be a free parameter to it is skipped 237 | // otherwise we have 2 modes: 238 | // PREFER_FLAG_FOR_UNREG_OPTION: a non-registered 'name' is determined a flag. 239 | // The following value (the next arg) will be a free parameter. 240 | // 241 | // PREFER_PARAM_FOR_UNREG_OPTION: a non-registered 'name' is determined a parameter, the next arg 242 | // will be the value of that option. 243 | 244 | assert(!(mode & argh::parser::PREFER_FLAG_FOR_UNREG_OPTION) 245 | || !(mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION)); 246 | 247 | bool preferParam = mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION; 248 | 249 | if (is_param(name) || preferParam) 250 | { 251 | params_.insert({ name, args_[i + 1] }); 252 | ++i; // skip next value, it is not a free parameter 253 | continue; 254 | } 255 | else 256 | { 257 | flags_.emplace(name); 258 | } 259 | }; 260 | } 261 | 262 | ////////////////////////////////////////////////////////////////////////// 263 | 264 | inline string_stream parser::bad_stream() const 265 | { 266 | string_stream bad; 267 | bad.setstate(std::ios_base::failbit); 268 | return bad; 269 | } 270 | 271 | ////////////////////////////////////////////////////////////////////////// 272 | 273 | inline bool parser::is_number(std::string const& arg) const 274 | { 275 | // inefficient but simple way to determine if a string is a number (which can start with a '-') 276 | std::istringstream istr(arg); 277 | double number; 278 | istr >> number; 279 | return !(istr.fail() || istr.bad()); 280 | } 281 | 282 | ////////////////////////////////////////////////////////////////////////// 283 | 284 | inline bool parser::is_option(std::string const& arg) const 285 | { 286 | assert(0 != arg.size()); 287 | if (is_number(arg)) 288 | return false; 289 | return '-' == arg[0]; 290 | } 291 | 292 | ////////////////////////////////////////////////////////////////////////// 293 | 294 | inline std::string parser::trim_leading_dashes(std::string const& name) const 295 | { 296 | auto pos = name.find_first_not_of('-'); 297 | return std::string::npos != pos ? name.substr(pos) : name; 298 | } 299 | 300 | ////////////////////////////////////////////////////////////////////////// 301 | 302 | inline bool argh::parser::got_flag(std::string const& name) const 303 | { 304 | return flags_.end() != flags_.find(trim_leading_dashes(name)); 305 | } 306 | 307 | ////////////////////////////////////////////////////////////////////////// 308 | 309 | inline bool argh::parser::is_param(std::string const& name) const 310 | { 311 | return registeredParams_.count(name); 312 | } 313 | 314 | ////////////////////////////////////////////////////////////////////////// 315 | 316 | inline bool parser::operator[](std::string const& name) const 317 | { 318 | return got_flag(name); 319 | } 320 | 321 | ////////////////////////////////////////////////////////////////////////// 322 | 323 | inline bool parser::operator[](std::initializer_list init_list) const 324 | { 325 | return std::any_of(init_list.begin(), init_list.end(), [&](char const* const name) { return got_flag(name); }); 326 | } 327 | 328 | ////////////////////////////////////////////////////////////////////////// 329 | 330 | inline std::string const& parser::operator[](size_t ind) const 331 | { 332 | if (ind < pos_args_.size()) 333 | return pos_args_[ind]; 334 | return empty_; 335 | } 336 | 337 | ////////////////////////////////////////////////////////////////////////// 338 | 339 | inline string_stream parser::operator()(std::string const& name) const 340 | { 341 | auto optIt = params_.find(trim_leading_dashes(name)); 342 | if (params_.end() != optIt) 343 | return string_stream(optIt->second); 344 | return bad_stream(); 345 | } 346 | 347 | ////////////////////////////////////////////////////////////////////////// 348 | 349 | inline string_stream parser::operator()(std::initializer_list init_list) const 350 | { 351 | for (auto& name : init_list) 352 | { 353 | auto optIt = params_.find(trim_leading_dashes(name)); 354 | if (params_.end() != optIt) 355 | return string_stream(optIt->second); 356 | } 357 | return bad_stream(); 358 | } 359 | 360 | ////////////////////////////////////////////////////////////////////////// 361 | 362 | template 363 | string_stream parser::operator()(std::string const& name, T&& def_val) const 364 | { 365 | auto optIt = params_.find(trim_leading_dashes(name)); 366 | if (params_.end() != optIt) 367 | return string_stream(optIt->second); 368 | 369 | std::ostringstream ostr; 370 | ostr << def_val; 371 | return string_stream(ostr.str()); // use default 372 | } 373 | 374 | ////////////////////////////////////////////////////////////////////////// 375 | 376 | // same as above but for a list of names. returns the first value to be found. 377 | template 378 | string_stream parser::operator()(std::initializer_list init_list, T&& def_val) const 379 | { 380 | for (auto& name : init_list) 381 | { 382 | auto optIt = params_.find(trim_leading_dashes(name)); 383 | if (params_.end() != optIt) 384 | return string_stream(optIt->second); 385 | } 386 | std::ostringstream ostr; 387 | ostr << def_val; 388 | return string_stream(ostr.str()); // use default 389 | } 390 | 391 | ////////////////////////////////////////////////////////////////////////// 392 | 393 | inline string_stream parser::operator()(size_t ind) const 394 | { 395 | if (pos_args_.size() <= ind) 396 | return bad_stream(); 397 | 398 | return string_stream(pos_args_[ind]); 399 | } 400 | 401 | ////////////////////////////////////////////////////////////////////////// 402 | 403 | template 404 | string_stream parser::operator()(size_t ind, T&& def_val) const 405 | { 406 | if (pos_args_.size() <= ind) 407 | { 408 | std::ostringstream ostr; 409 | ostr << def_val; 410 | return string_stream(ostr.str()); 411 | } 412 | 413 | return string_stream(pos_args_[ind]); 414 | } 415 | 416 | ////////////////////////////////////////////////////////////////////////// 417 | 418 | inline void parser::add_param(std::string const& name) 419 | { 420 | registeredParams_.insert(trim_leading_dashes(name)); 421 | } 422 | 423 | ////////////////////////////////////////////////////////////////////////// 424 | 425 | inline void parser::add_params(std::initializer_list init_list) 426 | { 427 | for (auto& name : init_list) 428 | registeredParams_.insert(trim_leading_dashes(name)); 429 | } 430 | } 431 | 432 | 433 | -------------------------------------------------------------------------------- /cbp2ndk/src/extern/tixml2cx.h: -------------------------------------------------------------------------------- 1 | /* 2 | tinyxml2ex - a set of add-on classes and helper functions bringing C++11/14 features, such as iterators, strings and exceptions, to tinyxml2 3 | 4 | tixml2cx.h implements the copy operations of tinyxml2ex 5 | these copy a branch of an xml document to another document or another location within the same document, 6 | optionally substituting element parameter values to allow customisation of templated xml snippets 7 | it is separate from the base tinyxml2 extensions because it uses an additional collection class (unordered_map) 8 | 9 | 10 | Copyright (c) 2017 Stan Thomas 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 13 | to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | 23 | 24 | tinyxml2 is the work of Lee Thomason (www.grinninglizard.com) and others. 25 | It can be found here: https://github.com/leethomason/tinyxml2 and has it's own licensing terms. 26 | 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #ifndef __TINYXML_EX__ 33 | #include 34 | #endif // !__TINYXML_EX__ 35 | 36 | namespace tinyxml2 37 | { 38 | inline namespace tixml2ex 39 | { 40 | class XMLCopy : public XMLVisitor 41 | { 42 | public: 43 | XMLCopy (XMLElement * target) : _target(target) { _newDoc = target->GetDocument(); } 44 | 45 | virtual bool VisitEnter (const XMLElement & element, const XMLAttribute * attribute) override 46 | { 47 | auto e = _newDoc->NewElement (element.Name()); 48 | _target->InsertEndChild (e); 49 | while (attribute) 50 | { 51 | e->SetAttribute (attribute->Name(), attribute->Value()); 52 | attribute = attribute->Next(); 53 | } 54 | _target = e; 55 | return true; 56 | } 57 | 58 | virtual bool VisitExit (const XMLElement & element) override 59 | { 60 | _target = const_cast (_target->Parent()->ToElement()); 61 | return true; 62 | } 63 | 64 | virtual bool Visit (const XMLDeclaration & declaration) override 65 | { 66 | auto d = declaration.ShallowClone (_newDoc); 67 | _target->InsertEndChild (d); 68 | return true; 69 | } 70 | 71 | virtual bool Visit (const XMLText & txt) override 72 | { 73 | auto t = txt.ShallowClone (_newDoc); 74 | _target->InsertEndChild (t); 75 | return true; 76 | } 77 | 78 | virtual bool Visit (const XMLComment & comment) override 79 | { 80 | auto c = comment.ShallowClone (_newDoc); 81 | _target->InsertEndChild (c); 82 | return true; 83 | } 84 | 85 | protected: 86 | XMLElement * _target; 87 | XMLDocument * _newDoc; 88 | }; // XMLCopy 89 | 90 | 91 | class XMLCopyAndReplace : public XMLCopy 92 | { 93 | public: 94 | XMLCopyAndReplace (XMLElement * target, const std::unordered_map & params, char openDelim, char closeDelim) 95 | : XMLCopy(target), _params(params), _openDelim(openDelim), _closeDelim(closeDelim) {} 96 | 97 | bool VisitEnter (const XMLElement & element, const XMLAttribute * attribute) override 98 | { 99 | if (XMLCopy::VisitEnter (element, attribute)) 100 | { 101 | auto a = const_cast (_target->FirstAttribute()); 102 | while (a) 103 | { 104 | auto subst = substitute (a->Value()); 105 | if (subst.first) 106 | a->SetAttribute (subst.second.c_str()); 107 | a = const_cast (a->Next()); 108 | } 109 | return true; 110 | } 111 | else 112 | return false; 113 | } 114 | 115 | virtual bool Visit (const XMLText & txt) override 116 | { 117 | if (XMLCopy::Visit (txt)) 118 | { 119 | auto t = _target->LastChild()->ToText(); // it's the element text 'cos that the last one we added 120 | if (!t->CData()) // we don't substitute CDATA 121 | { 122 | auto subst = substitute (t->Value()); 123 | if (subst.first) 124 | t->SetValue (subst.second.c_str()); 125 | } 126 | return true; 127 | } 128 | else 129 | return false; 130 | } 131 | 132 | private: 133 | std::pair substitute (const std::string & val) 134 | { 135 | bool substituted{ false }; 136 | std::string newValue; 137 | std::string::size_type cursor = 0; 138 | auto ps = val.find (_openDelim); 139 | while (ps != std::string::npos) 140 | { 141 | newValue += val.substr (cursor, ps - cursor); 142 | auto pe = val.find (_closeDelim, ps); 143 | if (pe != std::string::npos) 144 | { 145 | cursor = pe + 1; 146 | auto px = _params.find (val.substr (ps + 1, pe - ps - 1)); 147 | if (px != _params.end()) 148 | { 149 | newValue += px->second; 150 | } 151 | else 152 | throw XmlException ("no value for parameter " + (val.substr (ps + 1, pe - ps - 1))); 153 | substituted = true; 154 | ps = val.find (_openDelim, pe); 155 | } 156 | else 157 | { 158 | ps = std::string::npos; 159 | break; 160 | } 161 | } 162 | if (substituted) 163 | return std::make_pair (true, newValue + val.substr (cursor, ps - cursor)); 164 | else 165 | return std::make_pair (false, val); 166 | } 167 | 168 | private: 169 | const std::unordered_map & _params; 170 | const char _openDelim; 171 | const char _closeDelim; 172 | 173 | }; // XMLCopyAndReplace 174 | 175 | 176 | inline void xcopy (const XMLElement * source, XMLElement * destinationParent) 177 | { 178 | XMLCopy copier (destinationParent); 179 | source->Accept (&copier); 180 | } 181 | 182 | 183 | inline void xcopy (const XMLElement * source, XMLElement * destinationParent, const std::unordered_map & params, char openDelim = '{', char closeDelim = '}') 184 | { 185 | XMLCopyAndReplace copier (destinationParent, params, openDelim, closeDelim); 186 | source->Accept (&copier); 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /cbp2ndk/version.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSION_LOCAL_H 2 | #define VERSION_LOCAL_H 3 | 4 | //Date Version Types 5 | #define CBP_DATE "03" 6 | #define CBP_MONTH "07" 7 | #define CBP_YEAR "2019" 8 | #define CBP_UBUNTU_VERSION_STYLE "19.07" 9 | 10 | //Software Status 11 | #define CBP_STATUS "" 12 | #define CBP_STATUS_SHORT "" 13 | 14 | //Standard Version Type 15 | #define CBP_MAJOR 0 16 | #define CBP_MINOR 0 17 | #define CBP_BUILD 1 18 | #define CBP_REVISION 4 19 | 20 | //Miscellaneous Version Types 21 | #define CBP_BUILDS_COUNT 0 22 | #define CBP_RC_FILEVERSION 0,0,1,4 23 | #define CBP_RC_FILEVERSION_STRING "0, 0, 1, 4\0" 24 | #define CBP_FULLVERSION_STRING "0.0.1.4" 25 | 26 | //These values are to keep track of your versioning state, don't modify them. 27 | #define CBP_BUILD_HISTORY 1 28 | 29 | 30 | #endif //VERSION_LOCAL_H 31 | -------------------------------------------------------------------------------- /docs/ADBANDROIDVIEWER.EN.md: -------------------------------------------------------------------------------- 1 | 2 | # ADB Android remote Viewer 3 | 4 | > Android Viewer developed to view and control your android device from a PC. 5 | > ADB exchange Android Viewer, support scale view, input tap from mouse, input swipe from keyboard, more features.. 6 | 7 | ---------- 8 | 9 | ![adbviewer](img/adbviewer-1-en.png) 10 | 11 | ### Download 12 | 13 | `ADB Android Viewer` msi package, `Bender Rodriguez edition :)` [msi](https://clnviewer.github.io/ADB-Android-Viewer/dist/Android-ADB-Viewer.msi) 14 | `ADB Android Viewer` single executable](https://clnviewer.github.io/ADB-Android-Viewer/dist/ADBViewer.exe) does not require installation, always ready to work, includes ADB 15 | 16 | 17 | ### ADB Viewer LUA script record 18 | 19 | ![adbviewer](img/adbviewer-script-record.gif) 20 | 21 | ### ADB Viewer LUA script run 22 | 23 | ![adbviewer](img/adbviewer-script-run.gif) 24 | 25 | ### ADB Viewer Terminal screen 26 | 27 | ![adbviewer](img/adbviewer-terminal.gif) 28 | 29 | > full screen mode 30 | 31 | ![adbviewer](img/adbviewer-2-terminal-en.png) 32 | 33 | ## License 34 | 35 | _MIT_ 36 | 37 | -------------------------------------------------------------------------------- /docs/ADBANDROIDVIEWER.RU.md: -------------------------------------------------------------------------------- 1 | 2 | # ADB Android remote Viewer 3 | 4 | > Android Viewer разработан для просмотра и управления устройством Android с ПК. 5 | > ADB Android Viewer - графическое приложение отображающее экран мобильного устройства с возможностью управления. Поддержка масштабного просмотра, ввод касания с помощью мыши, пролистывание ввода с клавиатуры, скриншоты, выбор устройств, управление АДБ менеджером и другие функции.. 6 | 7 | ---------- 8 | 9 | ![adbviewer](img/adbviewer-1-ru.png) 10 | 11 | ### Download 12 | 13 | `ADB Android Viewer` msi пакет, `Бендер Родригес edition :)` [msi](https://clnviewer.github.io/ADB-Android-Viewer/dist/Android-ADB-Viewer.msi) 14 | `ADB Android Viewer` сборка одним исполняемым файлом](https://clnviewer.github.io/ADB-Android-Viewer/dist/ADBViewer.exe) не требует инсталляции, всегда готов к работе, включает в себя ADB 15 | 16 | ### ADB Viewer - запись LUA скрипта 17 | 18 | ![adbviewer](img/adbviewer-script-record.gif) 19 | 20 | ### ADB Viewer - запуск LUA скрипта 21 | 22 | ![adbviewer](img/adbviewer-script-run.gif) 23 | 24 | ### ADB Viewer - экран встроенного тераминала 25 | 26 | ![adbviewer](img/adbviewer-terminal.gif) 27 | 28 | > полноэкранный режим 29 | 30 | ![adbviewer](img/adbviewer-2-terminal-en.png) 31 | 32 | ## License 33 | 34 | _MIT_ 35 | 36 | -------------------------------------------------------------------------------- /docs/CBNDKAUTOINSTALL.EN.md: -------------------------------------------------------------------------------- 1 | ### Installing the NDK installer C :: B template 2 | 3 | ---------- 4 | 5 | - Download the installer `NDK C::B template` [CodeBlocksNdkTemplate v.0.0.14.79 / win32 (07/03/2019)](https://clnviewer.github.io/Code-Blocks-Android-NDK/CodeBlocksNdkTemplate.exe) 6 | - Run the installer and install the `NDK C::B template` 7 | - If you did not select the "Overwrite C::B template configuration (v.17.12)" option during installation, you need to register the template yourself in the `Code :: Blocks` configuration file. 8 | - Edit the file `config.script` and add the template to the list used. 9 | 10 | ### Editing the C::B file with config.script 11 | 12 | The file must be in the following path: 13 | ``` 14 | \share\CodeBlocks\templates\wizard\config.script 15 | 16 | ``` 17 | 18 | You must add the following code to the `RegisterWizards()` function: 19 | ``` 20 | function RegisterWizards() 21 | { 22 | //... 23 | RegisterWizard( 24 | wizProject, 25 | _T("ndk_android"), 26 | _T("NDK Android"), 27 | _T("Native") 28 | ); 29 | //... 30 | ``` 31 | 32 | Before using the template, after making these changes, you must restart `C::B` 33 | 34 | 35 | ### NDK C::B template Wizard 36 | 37 | ![Image1](img/Wizard1.png) 38 | 39 | ![Image1](img/Wizard2.png) 40 | 41 | ![Image1](img/Wizard3.png) 42 | 43 | ![Image1](img/Wizard4.png) 44 | 45 | ![Image1](img/Wizard5.png) 46 | 47 | ![Image1](img/Wizard6.png) 48 | 49 | ![Image1](img/Wizard7.png) 50 | 51 | 52 | ### Features 53 | 54 | > __Bug?__: unfortunately I did not find a direct way to add debugger parameters directly to the `C::B` project using its API. 55 | > Currently, the debugger parameters are entered into the `Extensions/debugger1` section, but for operation it is necessary that these parameters be in the `Extensions/debugger` section. 56 | > After creating the project, use the editor to remove the `Extensions/debugger` section and rename the `Extensions/debugger1` section to `Extensions/debugger`. 57 | > An example of the contents of this section is given below. 58 | 59 | ```xml 60 | 61 | /// One actually platform path 62 | // 63 | // 64 | // 65 | 66 | 67 | 74 | 75 | 76 | ``` 77 | 78 | > __Attention!__: the `cbp2ndk` and `android-elf-cleaner` utilities used in `NDK C::B template` are built for the 32bit version of Windows. 79 | > If you are using a 64bit platform and want to have executable files of the corresponding bitness, you need to rebuild the project yourself. 80 | > The `cbp2ndk` and `android-elf-cleaner` utilities in `C::B` are located along the following path: 81 | 82 | ``` 83 | \share\CodeBlocks\templates\wizard\ndk_android\exec\ 84 | ``` 85 | 86 | ## License 87 | 88 | _MIT_ 89 | 90 | -------------------------------------------------------------------------------- /docs/CBNDKAUTOINSTALL.RU.md: -------------------------------------------------------------------------------- 1 | 2 | ### Установка инсталлятора NDK C::B template 3 | 4 | ---------- 5 | 6 | - Скачать инсталлятор `NDK C::B template` [CodeBlocksNdkTemplate v.0.0.14.79/win32 (03.07.2019)](https://clnviewer.github.io/Code-Blocks-Android-NDK/CodeBlocksNdkTemplate.exe) 7 | - Запустить инсталлятор и установить `NDK C::B template` 8 | - Если вы не выбрали пункт "Overwrite C::B template configuration (v.17.12)" во время установки, вам необходимо прописать темплейт самомтоятельно в конфигурационном файле `Code::Blocks`. 9 | - Отредактировать файл `config.script` и добавить темплейт в список используемых. 10 | 11 | ### Редактирование файла C::B config.script 12 | 13 | Файл должен находиться по следующему пути: 14 | 15 | ``` 16 | \share\CodeBlocks\templates\wizard\config.script 17 | 18 | ``` 19 | 20 | Необходимо добавить следующий код в функцию `RegisterWizards()`: 21 | 22 | ``` 23 | function RegisterWizards() 24 | { 25 | //... 26 | RegisterWizard( 27 | wizProject, 28 | _T("ndk_android"), 29 | _T("NDK Android"), 30 | _T("Native") 31 | ); 32 | //... 33 | 34 | ``` 35 | 36 | Перед использованием темплейта, после внесения этих изменений необходимо перезапустить `C::B` 37 | 38 | ### NDK C::B template Wizard 39 | 40 | ![Image1](img/Wizard1.png) 41 | 42 | ![Image1](img/Wizard2.png) 43 | 44 | ![Image1](img/Wizard3.png) 45 | 46 | ![Image1](img/Wizard4.png) 47 | 48 | ![Image1](img/Wizard5.png) 49 | 50 | ![Image1](img/Wizard6.png) 51 | 52 | ![Image1](img/Wizard7.png) 53 | 54 | 55 | ### Особенности 56 | 57 | > __Баг?__: к сожалению я не нашел прямого пути добавления параметров отладчика непосредственно в проект `C::B` с помощью его API. 58 | > На текущий момент параметры отладчика заносятся в секцию `Extensions/debugger1`, но для работы необходимо чтобы эти параметры были в секции `Extensions/debugger`. 59 | > После создания проекта необходимо с помощью редактора удалить секцию `Extensions/debugger`, а секцию `Extensions/debugger1` переименовать в `Extensions/debugger`. 60 | > Примерное содержимое этой секции приведено ниже. 61 | 62 | ```xml 63 | 64 | /// One actually platform path 65 | // 66 | // 67 | // 68 | 69 | 70 | 77 | 78 | 79 | ``` 80 | 81 | > __Внимание!__: утилиты `cbp2ndk` и `android-elf-cleaner` используемые в `NDK C::B template` собраны для 32bit версии Windows. 82 | > Если вы используете 64bit платформу и хотите иметь исполняемые файлы соответствующей разрядности, вам необходимо пересобрать проект самостоятельно. 83 | > Утилиты `cbp2ndk` и `android-elf-cleaner` в `C::B` находятся по следующкму пути: 84 | 85 | ``` 86 | \share\CodeBlocks\templates\wizard\ndk_android\exec\ 87 | ``` 88 | 89 | -------------------------------------------------------------------------------- /docs/CBP2NDK.EN.md: -------------------------------------------------------------------------------- 1 | ### cbp2ndk export utility 2 | 3 | The goal of the `cbp2ndk` utility is to transfer settings and settings made in `Code::Blocks` to the format of `Android NDK` 4 | 5 | ### Supported C::B configuration blocks: 6 | 7 | - both global settings blocks and corresponding tags are supported 8 | - compiler flags settings 9 | - setting options linker 10 | - list of link libraries 11 | - list of compiled project files 12 | 13 | 14 | ### Data conversion for NDK configuration, Android.mk file: 15 | 16 | - automatic calculation of paths for `include` and their inclusion in the variable `LOCAL_C_INCLUDES` 17 | - automatic calculation of connected libraries and their inclusion in the variable `LOCAL_LDLIBS` 18 | - automatic calculation of extensions of compiled files and their inclusion in the variable `LOCAL_CPP_EXTENSION` 19 | - automatic distribution of flags between the variables `LOCAL_CFLAGS` and `LOCAL_CPPFLAGS` according to their language 20 | - listing the compiled project files and adding them to the variable `LOCAL_SRC_FILES` 21 | - export the command line for the autorun application from `Project -> Program launch parameters` in `Makefile` and the startup script 22 | - if the file `Android.mk` is not in the directory pointed to by the path to the `.cbp` project, it will be created automatically. If you create `Android.mk`, the name for the application will be taken from the name of the project and all the specials. characters and spaces will be replaced with the underscore `_`. 23 | - the files `Application.mk` and `Makefile` in the absence of the directory pointed to by the path to the project `.cbp`, will be created automatically. In `Makefile` you need to edit the variable` NDKROOT` indicating the path to `Android NDK` on your system. 24 | - by default, the debug print library for Android, liblog is always included in the variable `LOCAL_LDLIBS`, and the project root directory is included in the variable `LOCAL_C_INCLUDES` 25 | 26 | 27 | ### Rewritable variables in the Android.mk file: 28 | 29 | The following variables can be overwritten, do not fill them in manually. 30 | 31 | - `LOCAL_CPP_EXTENSION` 32 | - `LOCAL_SRC_FILES` 33 | - `LOCAL_CFLAGS` 34 | - `LOCAL_CPPFLAGS` 35 | - `LOCAL_LDFLAGS` 36 | - `LOCAL_LDLIBS` 37 | - `LOCAL_C_INCLUDES` 38 | - `LOCAL_MODULE` (in case of file creation) 39 | 40 | Variables not included in this list will be saved with the values ​​and overwritten with the new configuration. 41 | 42 | ### Command line parameters: 43 | 44 | Options: 45 | -a, --auto find .cbp project file from current directory 46 | -c, --cbp path to .cbp project file 47 | -d, --dump dump current configuration 48 | -t, --tag building tag: Debug|Release|OtherTag 49 | -q, --quiet quiet all messages 50 | -v, --verbose verbose output to console 51 | -n --nodefault no set default values (libs, include paths) 52 | --cbtmpl install C::B wizard template Makefile file 53 | --api android API number (Application.mk) 54 | --abi android ABI platform (Application.mk) 55 | --ndkopt android NDK options (Application.mk) 56 | 57 | Using: 58 | cbp2ndk.exe 59 | cbp2ndk.exe -t -c -v 60 | cbp2ndk.exe -a --api android-28 --abi armeabi-v7a --ndkopt debug 61 | cbp2ndk.exe -a 62 | 63 | 64 | ### Adding a menu to C::B 65 | 66 | ![cbp2ndk menu in CodeBlocks](img/Image15.png) 67 | 68 | ### Sources: 69 | 70 | Download [cbp2ndk v.0.0.14.79 / win32 (07/03/2019)](https://clnviewer.github.io/Code-Blocks-Android-NDK/cbp2ndk.zip) 71 | See [cbp2ndk directory](https://github.com/ClnViewer/Code-Blocks-Android-NDK/tree/master/cbp2ndk) 72 | Learn more about the format and capabilities of the file [Android.mk](https://developer.android.com/ndk/guides/android_mk) 73 | 74 | 75 | ### Recommendations: 76 | 77 | > Always use a Unix-style slash (/) in assembly files. The build system incorrectly handles the backslash in Windows style. 78 | 79 | 80 | > Try not to change the level of optimization / debugging in your `Android.mk` file. This allows the build system to generate useful data files used during debugging. It is meant to exclude the use of the flags `-g`,` -s`, `-O` and their analogues. 81 | 82 | ## License 83 | 84 | _MIT_ 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /docs/CBP2NDK.RU.md: -------------------------------------------------------------------------------- 1 | 2 | # утилита экспорта cbp2ndk 3 | 4 | Цель утилиты `cbp2ndk`- перенос настроек и установок сделанных в `Code::Blocks` в формат `Android NDK` 5 | 6 | ### Поддерживаемые блоки конфигурации C::B: 7 | 8 | - поддерживаются как глобальные блоки настроек, так и соответствующие тегу сборки 9 | - настройки флагов компилятора 10 | - настройки опций линкера 11 | - список подключаемых библиотек 12 | - список компилируемых файлов проекта 13 | 14 | 15 | ### Преобразование данных для конфигурации NDK, файл Android.mk: 16 | 17 | - автоматическое вычисление путей для `include` и включение их в переменную `LOCAL_C_INCLUDES` 18 | - автоматическое вычисление подключаемых библиотек и включение их в переменную `LOCAL_LDLIBS` 19 | - автоматическое вычисление расширений компилируемых файлов и включение их в переменную `LOCAL_CPP_EXTENSION` 20 | - автоматическое распределение флагов между переменными `LOCAL_CFLAGS` и `LOCAL_CPPFLAGS` в соответствии с принадлежностью к языку 21 | - составление списка компилируемых файлов проекта и добавление их в переменную `LOCAL_SRC_FILES` 22 | - экспорт командной строки автозапуска приложения из `Проект -> Параметры запуска программы` в `Makefile` и скрипт запуска 23 | - если файл `Android.mk` отсутствует в каталоге на который указывает путь до проекта `.cbp`, он будет создан автоматически. В случае создания `Android.mk` имя для приложения будет взято из названия проекта и все спец. символы и пробелы будут заменены на нижнее подчеркивание `_`. 24 | - файлы `Application.mk` и `Makefile` в случае отсутствия в каталоге на который указывает путь до проекта `.cbp`, будут созданы автоматически. В `Makefile` необходимо отредактировать переменную `NDKROOT` указывающую на путь к `Android NDK` на вашей системе. 25 | - по умолчанию, в переменную `LOCAL_LDLIBS` всегда включается библиотека отладочной печати для `Android`, `liblog`, а в переменную `LOCAL_C_INCLUDES` включаеться корневая директория проекта `./` 26 | 27 | 28 | ### Перезаписываемые переменные в файле Android.mk: 29 | 30 | Указанные ниже переменные могут быть перезаписаны, не заполняйте их в ручную. 31 | 32 | - `LOCAL_CPP_EXTENSION` 33 | - `LOCAL_SRC_FILES` 34 | - `LOCAL_CFLAGS` 35 | - `LOCAL_CPPFLAGS` 36 | - `LOCAL_LDFLAGS` 37 | - `LOCAL_LDLIBS` 38 | - `LOCAL_C_INCLUDES` 39 | - `LOCAL_MODULE` (в случае создания файла) 40 | 41 | 42 | Переменные не вошедшие в этот список будут сохранены вместе со значениями и перезаписаны вместе с новой конфигурацией. 43 | 44 | ### Параметры командной строки: 45 | 46 | 47 | Options: 48 | -a, --auto find .cbp project file from current directory 49 | -c, --cbp path to .cbp project file 50 | -d, --dump dump current configuration 51 | -t, --tag building tag: Debug|Release|OtherTag 52 | -q, --quiet quiet all messages 53 | -v, --verbose verbose output to console 54 | -n --nodefault no set default values (libs, include paths) 55 | --cbtmpl install C::B wizard template Makefile file 56 | --api android API number (Application.mk) 57 | --abi android ABI platform (Application.mk) 58 | --ndkopt android NDK options (Application.mk) 59 | 60 | Using: 61 | cbp2ndk.exe 62 | cbp2ndk.exe -t -c -v 63 | cbp2ndk.exe -a --api android-28 --abi armeabi-v7a --ndkopt debug 64 | cbp2ndk.exe -a 65 | 66 | ### Добавление меню в C::B 67 | 68 | ![cbp2ndk menu in CodeBlocks](img/Image15.png) 69 | 70 | ### Источники: 71 | 72 | Скачать [cbp2ndk v.0.0.14.79/win32 (03.07.2019)](https://clnviewer.github.io/Code-Blocks-Android-NDK/cbp2ndk.zip) 73 | Перейти в директорию [cbp2ndk](https://github.com/ClnViewer/Code-Blocks-Android-NDK/tree/master/cbp2ndk) 74 | Более подробно о формате и возможностях файла [Android.mk](https://developer.android.com/ndk/guides/android_mk) 75 | 76 | ### Рекомендации: 77 | 78 | > Всегда используйте косую черту в стиле Unix (/) в файлах сборки. Система сборки неправильно обрабатывает обратную косую черту в стиле Windows. 79 | 80 | 81 | > Постарайтесь не изменять уровень оптимизации / отладки в вашем Android.mk файле. Это позволяет системе сборки генерировать полезные файлы данных, используемые во время отладки. Имеется в виду исключить употребление флагов `-g`, `-s`, `-O.` и их аналогов. 82 | 83 | ## License 84 | 85 | _MIT_ 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /docs/CodeBlocksNdkTemplate.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Code-Blocks-Android-NDK/bd65ca4424728887d86a6c267de233ae58373f1d/docs/CodeBlocksNdkTemplate.exe -------------------------------------------------------------------------------- /docs/README.EN.md: -------------------------------------------------------------------------------- 1 | 2 | Let's start small, how to screw the `Android NDK` to `C::B` 3 | 4 | There are two ways: 5 | 6 | - 1. register a profile for each platform, with executable files according to the platform. In my opinion it is tiring, a lot of things and it is not clear why. Given that if you collect the same for all platforms, the volume of gestures with switching configurations is quite large. My default is to build arm64-v8a, armeabi-v7a, x86, x86_64. 7 | - 2. use the native build system `ndk-build`. This is the simplest and most elegant solution that does not conflict with most of the `C::B` checks, but in the` C::B` settings every detail is important, the scheme is quite capricious, and with inaccuracies it can easily break. 8 | 9 | ### Solution features with ndk-build: 10 | 11 | - no rooted device required 12 | - full assembly debugging, without additional tools (NDK tool kit) 13 | - full build in `Debug/Release` modes 14 | - full launch of the application (from the device) 15 | - auto start/stop `gdbserver` from the device 16 | - no wrappers from `Gradle/Java` code required, works directly with the device 17 | - full integration of the `C::B` projects when using the export utility [cpb2ndk](CBP2NDK.EN.md). 18 | 19 | ### Android NDK Integration 20 | 21 | ---------- 22 | 23 | - __The first way__: download and install the ready installer `NDK C::B template`, [more ..](CBNDKAUTOINSTALL.EN.md) 24 | - __Path two__: in manual mode, set `NDK C::B template` for each project, as described below. 25 | 26 | ---------- 27 | 28 | The ideology and manner of building an application using the Android NDK toolchain is as close as possible to the typical behavior of `C::B`, the process logic: 29 | 30 | - build in the `Release` mode - stages: always a new build of the application, copying it to the device, launching the application. All actions are displayed in the console `C::B`. 31 | - build in `Debug` mode: always new build of application, copying it to device, copying `NDK-part` of files for debugging `gdbserver`, `gdb.setup`, launching `gdbserver` on device, waiting for connection of debager `GDB` for debugging. 32 | - `application launch` mode: steps: launching an application on a device with outputting results to the console. 33 | - `Debug -> Start` mode - stages: always a new build of the application, copying it to the device, copying the `NDK-part` files for debugging `gdbserv`, `gdb.setup`, launching `gdbserv` on the device, automatically connecting the debugger `GDB` and switch to debug mode. 34 | - in the `Debug`, `Debug -> Start` modes, the window being launched by `gdbserver` starts in a minimized state and automatically closes when the debugging is finished. 35 | 36 | 37 | ### Template files: 38 | 39 | The project itself `C::B`, important sections: 40 | 41 | - `