diff options
author | Raphael <raphael@google.com> | 2011-09-16 09:18:08 -0700 |
---|---|---|
committer | Raphael <raphael@google.com> | 2011-09-16 09:23:18 -0700 |
commit | fb098496a1460ed7b4bab997bc2acd96934236e7 (patch) | |
tree | b18963366b765122ace8210fdd4dbe469a88f013 | |
parent | 965869f3da4456d5a143e8bb98246734102f1f12 (diff) | |
download | sdk-fb098496a1460ed7b4bab997bc2acd96934236e7.zip sdk-fb098496a1460ed7b4bab997bc2acd96934236e7.tar.gz sdk-fb098496a1460ed7b4bab997bc2acd96934236e7.tar.bz2 |
AVD Launcher.exe for the Windows SDK.
In Tools R14, the Windows SDK will have 2 icons in the root
of the SDK: one to launch the AVD window, and a different one
to launche the SDK Manager window.
I'll need to change the icon in a later CL. I don't have
any ICO editor at hand right now.
Change-Id: Ic651e3c3d71c2eac5fe851fba8ea2782eca5e594
-rw-r--r-- | avdlauncher/.gitignore | 1 | ||||
-rw-r--r-- | avdlauncher/Android.mk | 56 | ||||
-rw-r--r-- | avdlauncher/NOTICE | 190 | ||||
-rw-r--r-- | avdlauncher/avdlauncher.c | 271 | ||||
-rwxr-xr-x | avdlauncher/avdlauncher.exe.manifest | 33 | ||||
-rw-r--r-- | avdlauncher/images/android_icon.ico | bin | 0 -> 300318 bytes | |||
-rw-r--r-- | avdlauncher/images/android_icon.rc | 2 | ||||
-rw-r--r-- | sdklauncher/Android.mk | 4 | ||||
-rw-r--r-- | sdklauncher/sdklauncher.c | 15 |
9 files changed, 562 insertions, 10 deletions
diff --git a/avdlauncher/.gitignore b/avdlauncher/.gitignore new file mode 100644 index 0000000..f20e626 --- /dev/null +++ b/avdlauncher/.gitignore @@ -0,0 +1 @@ +images/avdlauncher_icon.o diff --git a/avdlauncher/Android.mk b/avdlauncher/Android.mk new file mode 100644 index 0000000..fb48e15 --- /dev/null +++ b/avdlauncher/Android.mk @@ -0,0 +1,56 @@ +# Copyright 2011 The Android Open Source Project +# +# Android.mk for avdlauncher +# +# The "AVD Launcher" is for Windows only. +# This simple .exe will sit at the root of the Windows SDK +# and currently simply executes tools\android.bat. +# Eventually it should simply replace the batch file. + + +#----- The current C++ avdlauncher ----- + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +ifeq ($(HOST_OS),windows) + +LOCAL_SRC_FILES := \ + avdlauncher.c + +LOCAL_CFLAGS += -Wall -Wno-unused-parameter +LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE -DSH_HISTORY +LOCAL_MODULE := avdlauncher + +LOCAL_MODULE_TAGS := optional + +# Locate windres executable +WINDRES := windres +ifneq ($(USE_MINGW),) + # When building the resources under Linux, use the MinGW one + WINDRES := i586-mingw32msvc-windres +endif + +# Link the Windows icon file as well into the executable, based on the technique +# used in external/qemu/Makefile.android. The variables need to have different +# names to not interfere with the ones from qemu/Makefile.android. +# +INTERMEDIATE := $(call intermediates-dir-for,EXECUTABLES,$(LOCAL_MODULE),true) +AVDLAUNCHER_ICON_OBJ := avdlauncher_icon.o +AVDLAUNCHER_ICON_PATH := $(LOCAL_PATH)/images +$(AVDLAUNCHER_ICON_PATH)/$(AVDLAUNCHER_ICON_OBJ): $(AVDLAUNCHER_ICON_PATH)/android_icon.rc + $(WINDRES) $< -I $(AVDLAUNCHER_ICON_PATH) -o $@ + +# seems to be the only way to add an object file that was not generated from +# a C/C++/Java source file to our build system. and very unfortunately, +# $(TOPDIR)/$(LOCALPATH) will always be prepended to this value, which forces +# us to put the object file in the source directory... +# +LOCAL_PREBUILT_OBJ_FILES += images/$(AVDLAUNCHER_ICON_OBJ) + +include $(BUILD_HOST_EXECUTABLE) + +$(call dist-for-goals,droid,$(LOCAL_BUILT_MODULE)) + +endif + diff --git a/avdlauncher/NOTICE b/avdlauncher/NOTICE new file mode 100644 index 0000000..c5b1efa --- /dev/null +++ b/avdlauncher/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/avdlauncher/avdlauncher.c b/avdlauncher/avdlauncher.c new file mode 100644 index 0000000..ab2c88d --- /dev/null +++ b/avdlauncher/avdlauncher.c @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * The "AVD Manager" is for Windows only. + * This simple .exe will sit at the root of the Windows SDK + * and currently simply executes tools\android.bat. + * Eventually it should simply replace the batch file. + * + * TODO: replace by a jar-exe wrapper. + */ + +#ifdef _WIN32 + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <windows.h> + + +int _enable_dprintf = 0; + +void dprintf(char *msg, ...) { + va_list ap; + va_start(ap, msg); + + if (_enable_dprintf) { + vfprintf(stderr, msg, ap); + } + + va_end(ap); +} + +void display_error(LPSTR description) { + DWORD err = GetLastError(); + LPSTR s, s2; + + fprintf(stderr, "%s, error %ld\n", description, err); + + if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | /* dwFlags */ + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, /* lpSource */ + err, /* dwMessageId */ + 0, /* dwLanguageId */ + (LPSTR)&s, /* lpBuffer */ + 0, /* nSize */ + NULL) != 0) { /* va_list args */ + fprintf(stderr, "%s", s); + + s2 = (LPSTR) malloc(strlen(description) + strlen(s) + 5); + sprintf(s2, "%s\r\n%s", description, s); + MessageBox(NULL, s2, "Android AVD Manager - Error", MB_OK); + free(s2); + LocalFree(s); + } +} + + +HANDLE create_temp_file(LPSTR temp_filename) { + + HANDLE file_handle = INVALID_HANDLE_VALUE; + LPSTR temp_path = (LPSTR) malloc(MAX_PATH); + + /* Get the temp directory path using GetTempPath. + GetTempFilename indicates that the temp path dir should not be larger than MAX_PATH-14. + */ + int ret = GetTempPath(MAX_PATH - 14, temp_path); + if (ret > MAX_PATH || ret == 0) { + display_error("GetTempPath failed"); + free(temp_path); + return INVALID_HANDLE_VALUE; + } + + /* Now get a temp filename in the temp directory. */ + if (!GetTempFileName(temp_path, "txt", 0, temp_filename)) { + display_error("GetTempFileName failed"); + + } else { + SECURITY_ATTRIBUTES sattr; + ZeroMemory(&sattr, sizeof(sattr)); + sattr.nLength = sizeof(SECURITY_ATTRIBUTES); + sattr.bInheritHandle = TRUE; + + file_handle = CreateFile(temp_filename, // filename + GENERIC_WRITE, // access: write + FILE_SHARE_READ, // share mode: read OK + &sattr, // security attributes + CREATE_ALWAYS, // create even if exists + FILE_ATTRIBUTE_NORMAL, // flags and attributes + NULL); // template + if (file_handle == INVALID_HANDLE_VALUE) { + display_error("Create temp file failed"); + } + } + + free(temp_path); + return file_handle; +} + + +void read_temp_file(LPSTR temp_filename) { + HANDLE handle; + + handle = CreateFile(temp_filename, // filename + GENERIC_READ, // access: read + FILE_SHARE_READ, // share mode: read OK + NULL, // security attributes + OPEN_EXISTING, // only open existing file + FILE_ATTRIBUTE_NORMAL, // flags and attributes + NULL); // template + + if (handle == INVALID_HANDLE_VALUE) { + display_error("Open temp file failed"); + return; + } + + /* Cap the size we're reading. + 4K is good enough to display in a message box. + */ + DWORD size = 4096; + + LPSTR buffer = (LPSTR) malloc(size + 1); + + LPSTR p = buffer; + DWORD num_left = size; + DWORD num_read; + do { + if (!ReadFile(handle, p, num_left, &num_read, NULL)) { + display_error("Read Output failed"); + break; + } + + num_left -= num_read; + p += num_read; + } while (num_read > 0); + + if (p != buffer) { + *p = 0; + + /* Only output the buffer if it contains special keywords WARNING or ERROR. */ + char* s1 = strstr(buffer, "WARNING"); + char* s2 = strstr(buffer, "ERROR"); + + if (s2 != NULL && s2 < s1) { + s1 = s2; + } + + if (s1 != NULL) { + /* We end the message at the first occurence of [INFO]. */ + s2 = strstr(s1, "[INFO]"); + if (s2 != NULL) { + *s2 = 0; + } + + MessageBox(NULL, s1, "Android AVD Manager - Output", MB_OK); + } + + } + + free(buffer); + + if (!CloseHandle(handle)) { + display_error("CloseHandle read temp file failed"); + } +} + + +int avd_launcher() { + int result = 0; + STARTUPINFO startup; + PROCESS_INFORMATION pinfo; + CHAR program_dir[MAX_PATH]; + int ret, pos; + CHAR temp_filename[MAX_PATH]; + HANDLE temp_handle; + + ZeroMemory(&pinfo, sizeof(pinfo)); + + temp_handle = create_temp_file(temp_filename); + if (temp_handle == INVALID_HANDLE_VALUE) { + return 1; + } + + ZeroMemory(&startup, sizeof(startup)); + startup.cb = sizeof(startup); + startup.dwFlags = STARTF_USESTDHANDLES; + startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + startup.hStdOutput = temp_handle; + startup.hStdError = temp_handle; + + /* get path of current program, to switch dirs here when executing the command. */ + ret = GetModuleFileName(NULL, program_dir, sizeof(program_dir)); + if (ret == 0) { + display_error("Failed to get program's filename:"); + result = 1; + } else { + /* Remove the last segment to keep only the directory. */ + pos = ret - 1; + while (pos > 0 && program_dir[pos] != '\\') { + --pos; + } + program_dir[pos] = 0; + } + + if (!result) { + dprintf("Program dir: %s\n", program_dir); + + ret = CreateProcess( + NULL, /* program path */ + "tools\\android.bat avd", /* command-line */ + NULL, /* process handle is not inheritable */ + NULL, /* thread handle is not inheritable */ + TRUE, /* yes, inherit some handles */ + CREATE_NO_WINDOW, /* we don't want a console */ + NULL, /* use parent's environment block */ + program_dir, /* use parent's starting directory */ + &startup, /* startup info, i.e. std handles */ + &pinfo); + + dprintf("CreateProcess returned %d\n", ret); + + if (!ret) { + display_error("Failed to execute tools\\android.bat:"); + result = 1; + } else { + dprintf("Wait for process to finish.\n"); + + WaitForSingleObject(pinfo.hProcess, INFINITE); + CloseHandle(pinfo.hProcess); + CloseHandle(pinfo.hThread); + } + } + + dprintf("Cleanup.\n"); + + if (!CloseHandle(temp_handle)) { + display_error("CloseHandle temp file failed"); + } + + if (!result) { + read_temp_file(temp_filename); + } + + if (!DeleteFile(temp_filename)) { + display_error("Delete temp file failed"); + } + + return result; +} + +int main(int argc, char **argv) { + _enable_dprintf = argc > 1 && strcmp(argv[1], "-v") == 0; + dprintf("Verbose debug mode.\n"); + + return avd_launcher(); +} + +#endif /* _WIN32 */ diff --git a/avdlauncher/avdlauncher.exe.manifest b/avdlauncher/avdlauncher.exe.manifest new file mode 100755 index 0000000..4cf055c --- /dev/null +++ b/avdlauncher/avdlauncher.exe.manifest @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<!--
+ For details on the Assembly Manifest, please look here:
+ http://msdn.microsoft.com/en-us/library/aa374191(VS.85).aspx
+-->
+
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+
+ <application>
+ <!--The ID below indicates application support for Windows Vista -->
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
+ <!--The ID below indicates application support for Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
+ </application>
+
+ <assemblyIdentity version="1.0.0.0"
+ processorArchitecture="x86"
+ name="Android.SDK.Launcher"
+ type="win32"
+ />
+
+ <description>Launches the Android SDK Manager to download Android SDK packages.</description>
+
+ <!-- Identify the application security requirements. -->
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
diff --git a/avdlauncher/images/android_icon.ico b/avdlauncher/images/android_icon.ico Binary files differnew file mode 100644 index 0000000..bd25179 --- /dev/null +++ b/avdlauncher/images/android_icon.ico diff --git a/avdlauncher/images/android_icon.rc b/avdlauncher/images/android_icon.rc new file mode 100644 index 0000000..fcf9049 --- /dev/null +++ b/avdlauncher/images/android_icon.rc @@ -0,0 +1,2 @@ +1 ICON "../images/android_icon.ico"
+1 RT_MANIFEST "../avdlauncher.exe.manifest"
diff --git a/sdklauncher/Android.mk b/sdklauncher/Android.mk index 8fda183..1f165f7 100644 --- a/sdklauncher/Android.mk +++ b/sdklauncher/Android.mk @@ -22,10 +22,12 @@ LOCAL_CFLAGS += -Wall -Wno-unused-parameter LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE -DSH_HISTORY LOCAL_MODULE := sdklauncher +LOCAL_MODULE_TAGS := optional + # Locate windres executable WINDRES := windres ifneq ($(USE_MINGW),) - # When building the Windows emulator under Linux, use the MinGW one + # When building the Windows resources under Linux, use the MinGW one WINDRES := i586-mingw32msvc-windres endif diff --git a/sdklauncher/sdklauncher.c b/sdklauncher/sdklauncher.c index d3c4445..570da86 100644 --- a/sdklauncher/sdklauncher.c +++ b/sdklauncher/sdklauncher.c @@ -20,10 +20,7 @@ * and currently simply executes tools\android.bat. * Eventually it should simply replace the batch file. * - * TODO: - * - create temp dir, always copy *.jar there, exec android.jar - * - get jars to copy from some file - * - use a version number to copy jars only if needed (tools.revision?) + * TODO: replace by a jar-exe wrapper. */ #ifdef _WIN32 @@ -223,7 +220,7 @@ int sdk_launcher() { ret = CreateProcess( NULL, /* program path */ - "tools\\android.bat update sdk", /* command-line */ + "tools\\android.bat sdk", /* command-line */ NULL, /* process handle is not inheritable */ NULL, /* thread handle is not inheritable */ TRUE, /* yes, inherit some handles */ @@ -232,7 +229,7 @@ int sdk_launcher() { program_dir, /* use parent's starting directory */ &startup, /* startup info, i.e. std handles */ &pinfo); - + dprintf("CreateProcess returned %d\n", ret); if (!ret) { @@ -240,13 +237,13 @@ int sdk_launcher() { result = 1; } else { dprintf("Wait for process to finish.\n"); - + WaitForSingleObject(pinfo.hProcess, INFINITE); CloseHandle(pinfo.hProcess); CloseHandle(pinfo.hThread); } } - + dprintf("Cleanup.\n"); if (!CloseHandle(temp_handle)) { @@ -267,7 +264,7 @@ int sdk_launcher() { int main(int argc, char **argv) { _enable_dprintf = argc > 1 && strcmp(argv[1], "-v") == 0; dprintf("Verbose debug mode.\n"); - + return sdk_launcher(); } |