Страницы

Поиск по вопросам

Показаны сообщения с ярлыком build. Показать все сообщения
Показаны сообщения с ярлыком build. Показать все сообщения

понедельник, 13 апреля 2020 г.

Android.mk: как правильно присоединить динамическую библиотеку?

#android #android_ndk #build

                    
Есть библиотека, назовем ее Library.so и инклуды к ней. Без jni. Нужно присоединить
ее к проекту. Для этого пишу jni обертку.
Собираю все следующим образом (Android.mk):
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := Library
LOCAL_SRC_FILES := Library.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := Library_jni
LOCAL_SRC_FILES := Library_jni.c 
LOCAL_LDLIBS += $(LOCAL_PATH)/../libs/armeabi/libLibrary.so
LOCAL_C_INCLUDES:= $(LOCAL_PATH)/include
include $(BUILD_SHARED_LIBRARY)

Все собирается нормально, но при выполнении:
static
{
    try{
            System.loadLibrary("Library_jni");
    }catch(UnsatisfiedLinkError use){
        Log.e("JNI","ERROR: Could not load Library_jni.so");
    }
}

сообщение об ошибке выводится. Если не отлавливать, вылетает с исключением:
Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1936]:
69 could not load needed library 'libLibrary.so' for 'libLibrary_jni.so' (load_library[1091]:
Library 'libLibrary.so' not found)

То есть библиотека-обертка не может загрузиться, потому что на найдена основная библиотека.
Как я понимаю, она ищется по адресу: $(LOCAL_PATH)/../libs/armeabi/libLibrary.so, но
на устройстве, само собой такой папки нет. На устройстве библиотеки лежат в data/data/my.package/lib.
Понятно, что она и не найдется.
Но при любом другом адресе в LOCAL_LDLIBS линковщик не может найти нужный файл, сборка
завершается с ошибкой. Если писать только
LOCAL_SHARE_LIBRARIES := libLibrary

линковщик не видит реализаций функций из внутренней библиотеки, заголовки видит нормально.
Как правильно сослаться на динамическую библиотеку из другой динамической библиотеки,
чтобы и на этапе сборки и на этапе выполнения не было ошибок? Можно сделать так, чтобы
при сборке библиотека искалась по одному адресу, а при выполнении по другому?    


Ответы

Ответ 1



Проблема в том, что загрузчик Андроида автоматически не подгружает зависимости. То есть если библиотека А зависит от библиотеки Б, то пользователь должен самостоятельно грузить библиотеку Б до библиотеки А. Вы можете обойти ограничение, если либо внедрите JNI в основную библиотеку, либо загрузите вручную (dlopen, dlclose) основную библиотеку из вспомогательной.

Ответ 2



Все оказалось просто, нужно подгружать библиотеки так: static { try{ System.loadLibrary("Library"); System.loadLibrary("Library_jni"); }catch(UnsatisfiedLinkError use){ use.printStackTrace(); } } Тогда все работает.

суббота, 11 апреля 2020 г.

Ошибка при прохождении сертификата Windows Store

#c_sharp #visual_studio #build #windows_phone_8 #microsoft_store

                    
В общем, пытаюсь сделать appx файл через VS. После компиляции пытаюсь пройти сертификацию,
валится на таком:

Проверка конфигурации отладки

ОШИБКА
Конфигурация отладки
Обнаружена ошибка: При тестировании конфигурации отладки обнаружены следующие ошибки:
Построение двоичного файла FFF.exe выполнено в режиме отладки.
Последствия, если проблема не устранена: Магазин Windows Phone не разрешает отлаженные
версии приложений.
Инструкции по исправлению: Убедитесь, что приложение не связано с отлаженными версиями
платформы и создано на основе конфигурации выпуска.


Суть в чем, Release мод стоит:

Что вообще VS хочет от меня?
    


Ответы

Ответ 1



В общем, проблема была в том что в одном из двух проектов не была выставлена галочка: Optimize code. Пруф на English SO.

вторник, 25 февраля 2020 г.

Разделение класса в заголовочный файл и в файл с кодом

#cpp #header #build


Вроде всегда так класс разделял в h-хедерные файлы и cpp-файлы с кодом, но в этот
раз что-то пошло не так :( 
Пишет Unresolved external blablabla.obj
Main  Header  CPP 
Подскажите, пожалуйста, где я в этот раз ошибся?    


Ответы

Ответ 1



Проблема в шаблонах. Шаблоны надо размещать полностью в header'е. Дело в том, что шаблонный класс не есть класс, и не генерирует вовсе никакого кода. Код будет сгенерирован «задним числом» в момент инстанциации шаблона, то есть, в тот момент, когда вы объявляете шаблон с конкретным параметром! (В вашем случае это main.) Если выгрузить имплементацию шаблона в .cpp, она будет в этой точке компиляции недоступна, и приведёт к ошибке компоновки. Есть, правда, ещё один путь: если вы точно знаете все типы, с которыми будет когда-либо инстанциироваться шаблон, вы можете оставить имплементацию в .cpp, и добавить туда список для явной инстанциации: template class Stack; Но это сработает только лишь если вы контролируете все места, где ваш шаблон будет использован. Если вы пишете библиотеку общего пользования, вы не можете знать наперёд, с какими типами её будут использовать клиенты, то есть этот трюк не пройдёт, и вам таки придётся писать всё в header'е. (Так работает вся STL, например.) Дополнительное чтение по теме: [C++ FAQ/Templates/linker errors].

среда, 12 февраля 2020 г.

Jenkins запуск build проекта после push

#gitlab #build #jenkins


Доброго времени суток. Первый раз столкнулся с задачами CI. Проблема - не получается
адекватно настроить Jenkins. Что требуется: после push проекта на GitLab (именно после
push, это важно), Jenkins должен попытаться собрать проект.

Шаги предпринятые для решения этой проблемы:


Jenkins сервер поднят и настроен, и работает по адресу jenkinsaddres:port
На Jenkins сервере есть GitLab connection опция которая настроена на gitlabhost,
GitLab API token задан и test connection возвращает радостное success.
Добавлен проект, Source Code Management, Repository URL, Credentials, Branch Specifier
настроены.
В проекте опции Build when a change is pushed to GitLab. GitLab CI Service URL: jenkinsaddres:port/project/test
активна, GitLab Triggers: Push events опция так же активна.
GitLabProject -> Settings -> Web hook -> jenkinsaddres:port/project/test, и опция
Push Events тоже активна.


Проект build'ится по расписанию, или вручную но никак не хочет собираться даже при
тестовой отправке hook'а с GitLab. POST сообщение доходит следующего вида source: gitlabhost;
destination: jenkinsaddres; Protocol: HTTP; info: POST /project/test HTTP/1.1 (application/json).
Ответ: адреса верные поэтому не буду их показывать, поле info: HTTP/1.1 404 Not Found
(text/html).

Если на Jenkins выключить все secure опции, и посылать hook на jenkinsaddres:port/job/test(сюда
он стягивает проекты) то тогда объект все-таки находится: Found. Но оказывается что
изменений Jenkins не видит (Not Modified), думаю поэтому проект и не ребилдится.
    


Ответы

Ответ 1



Борюсь с подобной же проблемой. Статья https://github.com/jenkinsci/gitlab-plugin/issues/298 дала следующую подсказку - тестируют с POST а не GET, что возвращает 403 так как "anonymous is missing the Job/Build permission". Два решения по починке https://github.com/jenkinsci/gitlab-plugin/issues/375 Если не заработает после правки - стоит проверить имя проекта. Если что есть URL encoded - это проблемма Так Unit Tests не работает, а UnitTests работает.

Ответ 2



Можно использовать триггер с токеном, он позволяет запускать сборку даже анонимному пользователю. Например, в моем дженкинсе аноним имеет разрешение только на просмотр (Read) задач и сборок. Но хуки работают из Гитлаба, curl'ом и просто через браузер. В конфигурации задачи example_jenkins_job: Хук в Гитлабе: http://jenkinsaddress:port/job/example_jenkins_job/build?token=secret_token Или, если задача параметризованная: http://jenkinsaddress:port/job/example_jenkins_job /buildWithParameters?token=secret_token В этом случае будет запущена сборка с дефолтными значениями параметров. Вы можете передавать собственные значения параметров следующим образом: http://jenkinsaddress:port/job/example_jenkins_job /buildWithParameters?token=secret_token¶m1=value1¶m2=value2 Можно добавить причину сборки: &cause=Cause+Text Она сохранится в информации о сборке: И в логе сборки, первой строкой: Started by remote host 127.0.0.1 with note: Cause Text

воскресенье, 26 января 2020 г.

Как правильно работать с dev и продакшн?

#git #build


Всем, привет!
Уважаемые, Git-знатоки, объясните, пожалуйста, как правильно работать с гитом.
Задача: разработка на локальной машине сайта и последующая отправка изменений в удаленный
репозиторий.
Что есть сейчас: локальный проект под версионным контролем (гит-репозиторий, в нем
-дцать коммитов), есть сервер (хостинг) с пустым гит-репозиторием.
Что было сделано (эксперименты): пробовал делать ветку build (она же продакшн), мержил
туда нужные файлы для сайта, пуш-ил в удаленный репозиторий, затем делал пулл из удаленого
репозиория - файлы подтягивались. Но так, видимо, до конца и не понял, в чем соль.
Ибо когда продолжал работать над проектом (master) и затем вливал в ветку build основную
ветку разработки, была куча ошибок мержа и не ничего не получалось в конечном итоге.
Как вижу разработку: есть основная ветка (мастер), в ней ведется разработка. Есть
продакшн-ветка, она же build. В продакшн-ветке разработка не ведется, а только принимаются
необходимые измнения из Мастера. Когда требуется внести изменения на сайт, делается
коммит. Затем этот коммит накатывается (???) на ветку build. После чего ветка билд
push-ится в пустой удаленный репозиторий. А из него в рабочий сайт (тоже под версионным
контролем) делается pull. Как-то так...
Прошу не судить строго, ибо мало опыта, и не лить "воды".
За качественный ответ-разъяснение, заранее благодарен!    


Ответы

Ответ 1



В отличие от 99% задающих здесь вопросы по git, вы всё делаете правильно. Разберитесь, почему у вас ошибки при мерже master'а в build, и жизнь заиграет новыми красками.

четверг, 23 января 2020 г.

Config файл при сборке Rpm-пакета

#linux #build #rpm


Собираю rpm-пакет. 
Имеется некоторый файл, содержимое которого одна строка с символов '1'.

В spec-файле имею следующие настройки сборки

%files
%defattr(-, root, root)

%config(noreplace) /path/file.config

%preun
echo "222" >> /path/file.config


То есть данный файл помечен как файл конфигурации. При удалении пакета я его модифицирую,
записываю туда некую строчку(в моем случае строку с 3-мя символа '2')

Собираю пакет, устанавливаю пакет на дистрибутив OpenSuse 13.2. Делаю установку пакета... 
После установки вижу, создался файл /path/file.config со строкой  с символом '1'(исходное
содержимое файла).
Меняю этот файл(чтобы он сохранился при удалении пакета), заменяю символ '1' на символ
'3'. 
Теперь пробую удалить мой установленный пакет.
При удалении пакета я прописал, чтобы у меня добавилась новая строка в этот файл "222".
После удаления пакета я ожидаю увидеть сохраненный файл, содержащий 2 строки

3
222


В итоге, я вижу файл с одной строкой(только последние изменения, сделанные до удаления
пакета)

3


То есть все изменения, которые я сделал в postun-скрипте для этого файла, они были
утеряны. Почему так происходит?
Установку делаю с помощью команды rpm -i, удаление пакета с помощью rpm -e.
Можно ли сделать так, чтобы конфигурационный файл менялся в postun-скрипте, и чтобы
rpm учитывала эти изменения при сохранении конфигурационного файла после удаления пакета?
    


Ответы

Ответ 1



попробуйте проверить, выполняется ли вообще скрипт из секции %preun, добавив в него, например, такую строку: %preun ... touch /tmp/somefile если файл /tmp/somefile не появится после удаления пакета, то стоит попробовать перенести секцию %preun выше секции %files: ... %preun ... %files ... обновление возможно, подходящим вариантом может быть отказ от управления нужным вам файлом средствами программы rpm. попробуйте вообще убрать его из секции %files, и просто создавать его (при необходимости) из образцового файла где-нибудь в секции, например, %post. этот вариант мне кажется более простым и менее затратным, чем попытки выяснить точную последовательность действий программы rpm при работе с файлами, объявленными как %config. что вы при этом «потеряете»? насколько я понимаю, лишь возможность проверить принадлежность файла с помощью rpm -qf /ваш/файл.

пятница, 10 января 2020 г.

Сборка проекта С++/С# из командной строки

#cmd #visual_studio_2015 #build


Требуется собрать проект с помощью bat-файла. Параметры сборки следующие:

MsVstudio\incredibuilder - тип сборки локальная\распределенная
win32\x64
debug\release
build\rebuild


Можно ли как-то при запуске VS передать в неё такие параметры? Читал про команду
devenv, она даёт возможность только указать Build или Rebuild.
    


Ответы

Ответ 1



Вам нужен MSBuild - это утилита от Майкрософта, которая умеет с командной строки собирать проекты. А вот прикрутить ее в бат файл - это уже простая задача. Как собрать проект в релизе? MSBuild.exe C:\Folder with Solution\My Solution.sln /property:Configuration=Release как собрать и дебаг, и релиз? MSBuild.exe C:\Folder with Solution\My Solution.sln /property:Configuration=Debug;Release Хочется чего то больше - читаем документацию https://msdn.microsoft.com/ru-ru/library/ms164311.aspx P.S. Возможно, придется запускать "VS2015 x86 Native Tools Command Prompt" (ну или под Вашу версию студии) и в его консоли уже выполнять сборку.

Ответ 2



В общем локальная сборка делается с помощью MSBuild, как мне посоветовали выше. Полный пример: msbuild.exe %SolutionPath% /t:build /p:configuration=release /p:platform=x86 Запускается из Bat, только после перехода в каталог, в котором находится MSBuild. Распределённая сборка, через IncrediBuild, делается через BuildConsole: BuildConsole.exe %SolutionPath% /build /cfg="release|x86" Является командой самой windows cmd, так что ничего придумывать не надо.

четверг, 9 января 2020 г.

Заменил в проекте все compile на implementation, но предупреждение осталось!

#android #android_studio #gradle #build #warning


Заменил абсолютно все compile на implementation в gradle по рекомендации (предупреждению)
Android Studio, но предупреждение (warning) продолжает меня предупреждать:


  Configuration 'compile' is obsolete and has been replaced with
  'implementation'

    


Ответы

Ответ 1



Обновил com.google.gms:google-services 3.1.1 на com.google.gms:google-services 3.2.0 и все OK! Предупреждений больше нет!

среда, 25 декабря 2019 г.

сборка предустановленного приложения

#android #сборка #build #apk


Существует ли разница между сборкой предустановленного приложения и сборкой стороннего
приложения? Отличается .apk-файлы первой от второй? Если есть разница, то в чем она?
Какие требования предъявляются? 
    


Ответы

Ответ 1



Не совсем уверен, что понимаю о чем идет речь, попробую ответить в меру своего понимания. У каждого вендора (то бишь производителя) телефонов (по крайней мере у серьезных вендоров) имеется свои системные сертификаты, которым их версия оси/оболочки безусловно доверяет, соответственно приложения подписанные такими сертификатами имеют доступ к пермишенам/API недоступным простым смертным. Здесь обсуждается способы хакинга подписи системными ключами. Ни разу не уверен, что все это работает, ибо чукча не хакер, а простой девелопер. Возвращаясь к вашему вопросу: Хочу узнать, могу отправить эту же сборку, или надо для производителя делать какую-то другую, отличную от моей? Сборка наверное должна быть другая, поскольку в любом случае отличается манифест, наличием атрибута: android:sharedUserId="android.uid.system" Но этот атрибут не будет активирован пока не появится подпись вендора под ним. Технически APK можно подписать несколькими ключами, но проблема в том, что маркет не понимает приложения с несколькими подписями. Так что вам как то надо будет договориться с вендором, чтобы они подписали ваш калькулятор своей подписью - иначе не взлетит. Как вариант им можно послать неподписанный APK, они сами и подпишут его.

понедельник, 23 декабря 2019 г.

Сокращение времени билда приложения

#java #android #gradle #build


Билд и запуск приложения в Android Studio 3.0 слишком долгий(иногда 20-25 минут)
при развертывании на Android 4.3. При этом при развертывании этого же приложения, на
устройствах с 5-6 андроидом билдится всего пару минут. От чего вообще может зависеть
скорость билда? И как можно сократить это время, оптимизировать
    


Ответы

Ответ 1



две полезные ссылки на эту тему: https://developer.android.com/studio/build/optimize-your-build.html https://medium.com/@kevalpatel2106/how-to-decrease-your-gradle-build-time-by-65-310b572b0c43 В частности почитайте как сделать профилирование билда. Как минимум локализуете проблему. также может быть Вам поможет выделение модулей из проекта. Они будут кэшироваться и билдиться параллельно(если в gradle.properties пропишите org.gradle.parallel=true) выжимка из второй статьи - измените gradle.properties так: #Enable daemon org.gradle.daemon=true # Try and findout the best heap size for your project build. org.gradle.jvmargs=-Xmx3096m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # Modularise your project and enable parallel build org.gradle.parallel=true # Enable configure on demand. org.gradle.configureondemand=true

воскресенье, 22 декабря 2019 г.

Как сделать так, чтобы при каждом Generate Signed APK автоматически увеличивался на единицу versionCode?

#android #android_studio #компиляция #build #android_manifest


Как сделать так, чтобы при каждом Generate Signed APK... автоматически увеличивался
на единицу versionCode, чтобы не делать это вручную,.. просто, иногда забываешь об
этом и загружаешь в Google Play Console версию со старым versionCode (что не допустимо!)

android:versionCode="X"

    


Ответы

Ответ 1



Решение 1 android { compileSdkVersion 18 buildToolsVersion "18.1.0" def versionPropsFile = file('version.properties') if (versionPropsFile.canRead()) { def Properties versionProps = new Properties() versionProps.load(new FileInputStream(versionPropsFile)) def code = versionProps['VERSION_CODE'].toInteger() + 1 versionProps['VERSION_CODE']=code.toString() versionProps.store(versionPropsFile.newWriter(), null) defaultConfig { versionCode code versionName "1.1" minSdkVersion 14 targetSdkVersion 18 } } else { throw new GradleException("Could not read version.properties!") } // rest of android block goes here } Решение 2 (использовать время) def date = new Date() def formattedDate = date.format('yyMMddHHmm') def code = formattedDate.toInteger() defaultConfig { minSdkVersion 10 targetSdkVersion 21 versionCode code }

Ответ 2



Я делаю по другому. В основе идеи лежит использование номера версии из VCS. В случае git делаем так: //извлечение порядкового номера версии стартуя от HEAD def getVersionCode = { -> try { def stdout = new ByteArrayOutputStream() exec { standardOutput = stdout commandLine 'git', 'rev-list', '--first-parent', '--count', 'master' } println("Build #"+stdout) return asInteger(stdout.toString("ASCII").trim()) } catch (Exception e) { e.printStackTrace(); return 0; } } //присваиваем версию def char[] patches='abcdefghijklmnopqrstuwxyz'.toCharArray() def patch=1 //иногда бывает нужно определить патч внутри версии def majorVersion=1 def minorVersion=0 def revision=getVersionCode() defaultConfig { //blah-blah versionName = majorVersion + '.' + minorVersion + '.' + revision + patches[patch] versionCode = 10000000*majorVersion+10000*minorVersion + 10*revision+patch } На выходе получим что-то типа: versionName="1.0.25a" versionCode="10000251" Аналогичные скрипты можно написать и для SVN Update Инкрементирование версии будет при каждом commit. Отдельно можно также писать githash с тем, чтобы потом по логам восстановить какая именно версия упала и где. Когда юзеров много, не все вовремя апгрейдят версии - крайне полезная штука скажу я вам. Несколько раз реально выручала.

воскресенье, 30 июня 2019 г.

Ошибка при прохождении сертификата Windows Store

В общем, пытаюсь сделать appx файл через VS. После компиляции пытаюсь пройти сертификацию, валится на таком:
Проверка конфигурации отладки
ОШИБКА Конфигурация отладки Обнаружена ошибка: При тестировании конфигурации отладки обнаружены следующие ошибки: Построение двоичного файла FFF.exe выполнено в режиме отладки. Последствия, если проблема не устранена: Магазин Windows Phone не разрешает отлаженные версии приложений. Инструкции по исправлению: Убедитесь, что приложение не связано с отлаженными версиями платформы и создано на основе конфигурации выпуска.
Суть в чем, Release мод стоит:
Что вообще VS хочет от меня?


Ответ

В общем, проблема была в том что в одном из двух проектов не была выставлена галочка: Optimize code. Пруф на English SO

вторник, 11 июня 2019 г.

Android Studio App

Всем привет. Написал я в общем программу(простенький мессенджер). Запустил на эмуляторе все норм, работает(версия на эмуляторе 7.1.1). Решил я про тестить на своем андроиде(версия андроида 6.0.1) ничего не работает, вылетает программа и пишет Unfortunately app has stopped. Заходил я такое на андроид монитор смотрел ошибки, все чисто никаких ошибок. Пытался я менять sdk версию в build.gradle но это не помогает все тоже самое. Устанавливал я apk-debug на свой андроид для тестирования. Как мне это исправить? За ранее спасибо.
Вот мой build.gradle:
apply plugin: 'com.android.application'
android { compileSdkVersion 26 buildToolsVersion '26.0.2' defaultConfig { applicationId "com.example.lado.chatapp" minSdkVersion 21 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets{ main{ jniLibs.srcDirs = ['libs'] } } packagingOptions { exclude 'META-INF/DEPENDENCIES.txt' exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE.txt' exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/notice.txt' exclude 'META-INF/license.txt' exclude 'META-INF/dependencies.txt' exclude 'META-INF/LGPL2.1' } }
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:26.+' compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.google.firebase:firebase-messaging:10.0.1' compile 'com.android.volley:volley:1.0.0' compile 'com.google.firebase:firebase-database:10.0.1' compile 'com.google.firebase:firebase-auth:10.0.1' compile 'com.firebase:firebase-client-android:2.5.2' compile 'com.google.firebase:firebase-storage:10.0.1'
compile 'com.github.liuguangqiang.swipeback:library:1.0.2@aar' testCompile 'junit:junit:4.12' }
apply plugin: 'com.google.gms.google-services'


Ответ

Все заработало. Что бы такой проблемы не было нужно зайти File -> Settings -> Build,Execution,Deployment ->Instant Run -> uncheck "Enable instant run". Просто отключить Instant Run.

вторник, 14 мая 2019 г.

Разделение класса в заголовочный файл и в файл с кодом

Вроде всегда так класс разделял в h-хедерные файлы и cpp-файлы с кодом, но в этот раз что-то пошло не так :( Пишет Unresolved external blablabla.obj Main Header CPP Подскажите, пожалуйста, где я в этот раз ошибся?


Ответ

Проблема в шаблонах. Шаблоны надо размещать полностью в header'е. Дело в том, что шаблонный класс не есть класс, и не генерирует вовсе никакого кода. Код будет сгенерирован «задним числом» в момент инстанциации шаблона, то есть, в тот момент, когда вы объявляете шаблон с конкретным параметром! (В вашем случае это main.) Если выгрузить имплементацию шаблона в .cpp, она будет в этой точке компиляции недоступна, и приведёт к ошибке компоновки. Есть, правда, ещё один путь: если вы точно знаете все типы, с которыми будет когда-либо инстанциироваться шаблон, вы можете оставить имплементацию в .cpp, и добавить туда список для явной инстанциации: template class Stack; Но это сработает только лишь если вы контролируете все места, где ваш шаблон будет использован. Если вы пишете библиотеку общего пользования, вы не можете знать наперёд, с какими типами её будут использовать клиенты, то есть этот трюк не пройдёт, и вам таки придётся писать всё в header'е. (Так работает вся STL, например.) Дополнительное чтение по теме: [C++ FAQ/Templates/linker errors]

четверг, 21 февраля 2019 г.

Сборка проекта С++/С# из командной строки

Требуется собрать проект с помощью bat-файла. Параметры сборки следующие:
MsVstudio\incredibuilder - тип сборки локальная\распределенная win32\x64 debug
elease build
ebuild
Можно ли как-то при запуске VS передать в неё такие параметры? Читал про команду devenv, она даёт возможность только указать Build или Rebuild.


Ответ

В общем локальная сборка делается с помощью MSBuild, как мне посоветовали выше.
Полный пример:
msbuild.exe %SolutionPath% /t:build /p:configuration=release /p:platform=x86
Запускается из Bat, только после перехода в каталог, в котором находится MSBuild.
Распределённая сборка, через IncrediBuild, делается через BuildConsole:
BuildConsole.exe %SolutionPath% /build /cfg="release|x86"
Является командой самой windows cmd, так что ничего придумывать не надо.

пятница, 15 февраля 2019 г.

Заменил в проекте все compile на implementation, но предупреждение осталось!

Заменил абсолютно все compile на implementation в gradle по рекомендации (предупреждению) Android Studio, но предупреждение (warning) продолжает меня предупреждать:
Configuration 'compile' is obsolete and has been replaced with 'implementation'


Ответ

Обновил
com.google.gms:google-services 3.1.1
на
com.google.gms:google-services 3.2.0
и все OK! Предупреждений больше нет!

среда, 28 ноября 2018 г.

сборка предустановленного приложения

Существует ли разница между сборкой предустановленного приложения и сборкой стороннего приложения? Отличается .apk-файлы первой от второй? Если есть разница, то в чем она? Какие требования предъявляются?


Ответ

Не совсем уверен, что понимаю о чем идет речь, попробую ответить в меру своего понимания.
У каждого вендора (то бишь производителя) телефонов (по крайней мере у серьезных вендоров) имеется свои системные сертификаты, которым их версия оси/оболочки безусловно доверяет, соответственно приложения подписанные такими сертификатами имеют доступ к пермишенам/API недоступным простым смертным.
Здесь обсуждается способы хакинга подписи системными ключами. Ни разу не уверен, что все это работает, ибо чукча не хакер, а простой девелопер.
Возвращаясь к вашему вопросу:
Хочу узнать, могу отправить эту же сборку, или надо для производителя делать какую-то другую, отличную от моей?
Сборка наверное должна быть другая, поскольку в любом случае отличается манифест, наличием атрибута:
android:sharedUserId="android.uid.system"
Но этот атрибут не будет активирован пока не появится подпись вендора под ним. Технически APK можно подписать несколькими ключами, но проблема в том, что маркет не понимает приложения с несколькими подписями. Так что вам как то надо будет договориться с вендором, чтобы они подписали ваш калькулятор своей подписью - иначе не взлетит. Как вариант им можно послать неподписанный APK, они сами и подпишут его.

понедельник, 19 ноября 2018 г.

Сокращение времени билда приложения

Билд и запуск приложения в Android Studio 3.0 слишком долгий(иногда 20-25 минут) при развертывании на Android 4.3. При этом при развертывании этого же приложения, на устройствах с 5-6 андроидом билдится всего пару минут. От чего вообще может зависеть скорость билда? И как можно сократить это время, оптимизировать


Ответ

две полезные ссылки на эту тему:
https://developer.android.com/studio/build/optimize-your-build.html
https://medium.com/@kevalpatel2106/how-to-decrease-your-gradle-build-time-by-65-310b572b0c43
В частности почитайте как сделать профилирование билда. Как минимум локализуете проблему.
также может быть Вам поможет выделение модулей из проекта. Они будут кэшироваться и билдиться параллельно(если в gradle.properties пропишите org.gradle.parallel=true)
выжимка из второй статьи - измените gradle.properties так:
#Enable daemon org.gradle.daemon=true
# Try and findout the best heap size for your project build. org.gradle.jvmargs=-Xmx3096m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# Modularise your project and enable parallel build org.gradle.parallel=true
# Enable configure on demand. org.gradle.configureondemand=true

вторник, 13 ноября 2018 г.

Как сделать так, чтобы при каждом Generate Signed APK автоматически увеличивался на единицу versionCode?

Как сделать так, чтобы при каждом Generate Signed APK... автоматически увеличивался на единицу versionCode, чтобы не делать это вручную,.. просто, иногда забываешь об этом и загружаешь в Google Play Console версию со старым versionCode (что не допустимо!)
android:versionCode="X"


Ответ

Решение 1
android { compileSdkVersion 18 buildToolsVersion "18.1.0"
def versionPropsFile = file('version.properties')
if (versionPropsFile.canRead()) { def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
def code = versionProps['VERSION_CODE'].toInteger() + 1
versionProps['VERSION_CODE']=code.toString() versionProps.store(versionPropsFile.newWriter(), null)
defaultConfig { versionCode code versionName "1.1" minSdkVersion 14 targetSdkVersion 18 } } else { throw new GradleException("Could not read version.properties!") }
// rest of android block goes here }
Решение 2 (использовать время)
def date = new Date() def formattedDate = date.format('yyMMddHHmm') def code = formattedDate.toInteger()
defaultConfig { minSdkVersion 10 targetSdkVersion 21 versionCode code }