Страницы

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

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

воскресенье, 15 марта 2020 г.

Не линкуются вместе загрузчик и ядро ОС

#gcc #сборка #os #osdev #ld


Я пытался написать примитивную ОС по урокам "Bare Bones" на osdev wiki. Проблема
заключается в том, что даже на самом начале ld выдает ошибку, что главная функция ядра,
_kmain, не определена. Итак, вот код:  

kernel.cpp  

    void _kmain() {  
        return;  
    }


boot.asm  

    ; This file is loaded by GRUB, Protected Mode is already enabled

    ; Multiboot constants

    MBALIGN equ 1<<0
    MEMINFO equ 1<<1
    FLAGS equ MBALIGN | MEMINFO
    MAGIC equ 0x1BADB002
    CHECKSUM equ -(MAGIC+FLAGS)

    ; Multiboot header

    section .multiboot
    align 4 ; Yes, I know, it's not necessary
        dd MAGIC
        dd FLAGS
        dd CHECKSUM

    ; Bootloader stack (we'll use another stack for OS, of course)

    section .bootstrap_stack, nobits
    align 4
        stack_bottom:
            resb 16384 ; 16K of stack, seems enough for a bootloader
        stack_top:

    section .text
        global _start
        _start:
        mov esp, stack_top ; Stack grows in a backwards direction
        extern _kmain
        call _kmain
        cli ; If _kmain returns, we will halt the computer
    .halt:
        hlt
        jmp .halt


Makefile

    ASM=nasm
    ASM_FLAGS=-felf32
    CC=/home/alexander/opt/cross/bin/i686-elf-g++
    CFLAGS=-ffreestanding -Wall -Wextra
    LINKER=/home/alexander/opt/cross/bin/i686-elf-gcc
    LFLAGS=-ffreestanding -nostdlib -lgcc -T linker.ld

    all: boot.o kernel.o
        $(LINKER) $(LFLAGS) -o kernel.bin $^
    boot.o:
        $(ASM) $(ASM_FLAGS) boot.asm -o boot.o

    kernel.o:
        $(CC) $(CFLAGS) -c kernel.cpp -o kernel.o

    screen.o:
        $(CC) $(CFLAGS) -c screen.cpp -o screen.o

    clean:
        rm *.o

    rmbaks:
        rm *~


linker.ld

    ENTRY(_start)
    SECTIONS {
        . = 1M;
        .text BLOCK(4K) : ALIGN(4K) {
            *(.multiboot)
            *(.text)
        }
        .rdata BLOCK(4K) : ALIGN(4K) {
            *(.rdata)
        }
        .data BLOCK(4K) : ALIGN(4K) {
            *(.data)
        }
        .bss BLOCK(4K) : ALIGN(4K) {
            *(COMMON)
            *(.bss)
            *(.bootstrap_stack)
        }
    }


Вывод после запуска make:

nasm -felf32 boot.asm -o boot.o
/home/alexander/opt/cross/bin/i686-elf-g++ -ffreestanding -Wall -Wextra -c kernel.cpp
-o kernel.o
/home/alexander/opt/cross/bin/i686-elf-gcc -ffreestanding -nostdlib -lgcc -T linker.ld
-o kernel.bin boot.o kernel.o
boot.o: In function `_start':
boot.asm:(.text+0x6): undefined reference to `_kmain'
collect2: error: ld returned 1 exit status
make: *** [all] Ошибка 1


P.S. В screen.cpp всякие полезные функции для работы с дисплеем, но он не используется.
    


Ответы

Ответ 1



На самом деле все просто упирается в компилятор. У Вас g++ (а не gcc). По умолчанию g++ формирует имена функций (те, что мы можем увидеть командой nm kernel.o) с учетом типа функции и параметров. Так, вместо ожидаемого _kmain, в .o получается _Z6_kmainv. Если Вы все еще хотите продолжать упражнения с С++, то придется явно сказать компилятору, что нужны имена функций в "сишном стиле". Для этого достаточно написать прототипы функций в специальном блоке: extern "C" { void _kmain(void); // это наш случай }; Если хотите, чтобы код без изменений (конечно, остальные его части тоже должны быть совместимы как с Си, так и с C++) компилировался также и gcc, то придется добавить немного директив препроцессора (к счастью он одинаков для g++/gcc) #ifdef __cplusplus extern "C" { #endif void _kmain(void); ... #ifdef __cplusplus }; #endif

воскресенье, 8 марта 2020 г.

Что включать в Docker-образ

#администрирование #веб_сервер #docker #сборка


Имеется веб-сайт на Django, на боевом сервере для запуска использую связку uWSGI/Nginx,
локальная разработка - virtualenv/dev-сервер Django

Из некоторых вопросов, которые задал на SO:


Распространение Docker-образов 
Запуск Docker-образов на боевом сервере
Запуск сайта из Docker-образа VS запуск c традиционными средствами (uWSGI, Nginx, Apache)


появилось еще пара.

Что включать в образ Docker?

Мы имеем production-версию и developer-версию. Как понимаю, в репозиториях распространяют
production. 

Имеет ли смысл создавать docker-образ для developer-версии (применительно ко мне,
код проекта и виртуальное окружение virtualenv)? Или разработчику достаточно только
кода из репозитория, чтобы начать разработку?

Где создают docker-образ production-версии?

На боевом сервере имеется проект, который работает на указанной связке - uwsgi/nginx/упаковщик
с production-настройками. Собирать образ я должен на боевом сервере?
    


Ответы

Ответ 1



Не должно быть понятия production и non-production версия образа. Разработчики, тестировщики, эксплуатационники и все остальные должны использовать одну и туже версию образа. Процесс разработки может быть устроен совершенно по разному, но если используется docker-образ (например, сервер разрабатываемый другой группой) в качестве внешней зависимости, то он должен браться из того же источника, что и для других нужд - тестирование, эксплуатация и т.п. Как, где и чем создают docker-образы? Процесс изготовления образа должен быть полностью автоматизирован, что бы избежать ошибок и сделать процесс повторяемым. Приблизительно процесс изготовления образа выглядит так (я опускаю некоторые шаги): Разработчик дописал код и протестировал его локально, в том числе и сборку образа. Разработчик заливает код в систему контроля версий. Робот собирает проект и создает артефакты для развертывания (мнифицирует все, объединяет в общий пакет и т.п.). Необязательный шаг - артефакты помещаются в хранилище. Робот собирает docker-образ. Необязательный шаг - робот подписывает образ. Робот заливает образ в реестр. Если нет специфических требовани, то для управления процессом создания можно использовать любой Continuous Integration сервер - Jenkins, TeamCity, Bamboo и т.д. У них у всех есть соответсвующие плагины или можно написать простые шел-скрипты и создавать образы стандартной командой docker build. Что включать в docker-образ? Сложно дать однозначный ответ на этот вопрос, так как многое зависит от типа образа и личных предпочтений. Я напишу как бы я поступил с сервером на Django. Я мало работал с Django, так что поправьте меня, если я говорю что-то несоответствующее действительности. Если проект только начинается и нагрузка на сервис будет маленькая, то я бы поместил все (кроме БД) в один образ. Т.е. образ будет содержать: Python фиксированной версии установленный как системный (без virtualenv и пр) nginx/Apache фиксированных версий с нужными настройками собственно ваше приложение, взятое как артефакт для развертывания и развернутое внутри образа БД либо в отдельный образ, либо на отдельный сервер без использования контейнерезации. Если БД идёт отдельным образом, то важно позаботится о сохранении данных на внешний (по отношению к контейнеру) раздел диска. В противном случае данные будут утеряны при перезапуске контейнера. Если нагрузка будет значительная и есть много статических страниц, то я бы сделал несколько образов: Образ со статическими страницами nginx/Apache статическая часть вашего приложения Образ с динамической частью Python часть вашего приложения (Django) Образ балансировщиком (необязательный) nginx/HAProxy/Varnish/etc Если проект очень большой, то возможно статическую и динамическую часть делают разные команды и в этом случае они и буду отвечать за подготовку Dockerfile к своей части проекта.

вторник, 28 января 2020 г.

Зачем нужен maven?

#java #maven #сборка


Здравствуйте, очень хотелось бы узнать, много пересмотрел и перечитал, но не могу
понять. Зачем нужен Maven, если есть IDE - Eclipse, Netbeans и т.д.? В чем его преимущество
по сборкам, если и IDE справляются?
    


Ответы

Ответ 1



Не совсем корректный вопрос, нельзя сравнивать Maven и среды разработки. C Maven можно работать и без сред разработки. Зачем нужен? Для управления зависимостями, для сборки проектов, и для кучи всего остального полезного. К примеру, ты пишешь большой проект и используешь в нем много технологий, к примеру, Hibernate, JUnit. Возникает вопрос как подключить все библиотеки? Ответ прост - просто прописать зависимости в pom.xml, а maven их скачает за тебя. Затем возможна такая ситуация, ты хочешь показать проект другу, отправляешь ему, но вот проблема, если это не проект Maven, то твоему другу придется скачивать библиотеки, чтобы проект заработал, а так за него это сделает Maven.С ростом твоих проектов - ты сам оценишь достоинства Maven. IDE справляются - а если нет IDE на твоем компьютере?Что будешь делать? На помощь приходит Maven, он кроссплатформенный и для работы с ним достаточно командной строки.

Ответ 2



IDE умеет собирать проект, но каждая делает это по разному - использует разную версию java, кодировку, структуру проекта, внешние библиотеки находятся в разных местах и могут иметь разную версию. Maven и другие системы сборки используются для унификации этого процесса. Они имеют ряд достоинств: с их помощью указываются версии библиотек, и что не маловажно, система знает откуда их брать. имеет устоявшуюся структуру проекта, это позволяет избежать путаницы и легче найти то что нужно. имеет определенный набор шагов - компиляция, тестирование, упаковка и тд. возможность кастомизации процесса сборки - добавления дополнительных шагов сборка не зависит от IDE, операционной системы и пр, т.к. можно указать версию компилятора, кодировку и пр.

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

Cборка Go под 64 битную систему на 32 битной ситеме

#golang #сборка


Возможно ли собрать код Go для 64 битной системы из под 32? Что для этого надо? 
Использую eclipce. Выставил переменное окружение в ide и обычное (GOARCH=amd64),
все равно собирается 32 битная версия.     


Ответы

Ответ 1



Наоборот точно можно, но нужны библиотеки для 32-битного кода. Соответственно тут тоже могут понадобиться библиотеки для 64-битного кода (если их нет в репозитории - надо будет настраивать руками). Попробуйте скачать Go 1.5 - там кросс-компиляция сделана уже заметно лучше и никаких внешних зависимостей для неё не требуется (например я из Windows компилирую бинарники для Linux, до 1.5 требовались пляски начиная с 1.5 - всё хорошо). Второй вариант: просто компилировать 32-битные бинарники - они на 64битной системе тоже будут работать. Если вам не требуется в работе больше 2Гб памяти конкретно для вашей программы думаю что разницы не будет.

Ответ 2



Имхо, там нужно сначала кросс-компилятор подготовить. Может, поможет: An introduction to cross compilation with Go

суббота, 11 января 2020 г.

Andoid. Debuggable приложение тормозит

#android #android_studio #отладка #сборка


Условия:

Я работаю на двух компьютерах - дома и на работе.
Я собираю одно и то же приложение с опцией debuggable=true.
Делаю я это на одном и том же девайсе.

Проблема:

При сборке на работе приложение не тормозит ни в debug buildType (будучи debuggable),
ни в release buildType.
Но стоит мне собрать его дома, как в debug buildType приложение начинает тормозить
на экранах с тяжелой версткой (множество 'ов). А если еще и в debug-режим
войти, то просто кромешный ад! При этом в release buildType все летает на тех же самых
экранах.

Вопрос:
Должны ли быть включены/выключены какие-то особые настройки Android Studio, чтобы
оптимизировать работу debuggable приложения? (вроде и на работе и дома ставил студию
одинаково, не изменяя каких-либо важных настроек). Быть может от самого компьютера
зависит скорость работы приложения на телефоне (звучит фантастически, но я уже не знаю
на что думать)
    


Ответы

Ответ 1



Подобное поведение может быть вызвано функцией Instant Run - она обновляет приложение в реальном времени при изменениях в коде в дебаг режиме. Это, надо полагать, требует постоянного обмена данными и их обработки, что нагружает и комп и девайс. Отключение оной может помочь.

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

Webpack. Сборка отдельных css и скриптов в общие файлы

#javascript #css #webpack #сборка


Как собрать разрозненные в проекте стили/скрипты в один файл (bundle.js/bundle.css)с
помощью webpack?

Проект содержит стили и скрипты для каждого приложения, которые лежат в отдельном
каталоге. Папка фронтенда:

├── frontend
│   ├── common
│   ├── node_modules
│   ├── app1
│   ├── app2
│   ├── app3
│   ├── ...
│   └── webpack.config.js


Папка каждого приложения имеет одинаковую структуру, но содержит разное количество
скриптов, стилей, шаблонов, который располагаются на одном уровне:

├── app
│   ├── static
│   │   └── app
│   │       ├── css
│   │       │   └── app.css
│   │       └── js
│   │           ├── app-detail.js
│   │           └── settings.js
│   └── templates
│       └── app
│           ├── app__element-detail.html
│           ├── app.html
│           ├── app__periodic-table.html
│           └── app__settings.html


Как собирать все эти файлы в один? 

Применительно к стилям - видел способ с extract-text-webpack-plugin, но во всех примерах
показыват один и тот же сценарий - одна точка входа, стили импортированы в скрипт и
из них уже собирается. 

Мне же нужно просто сделать бандл, его подключу в базовом шаблоне. 

Аналогичный вопрос можно задать и по сборке всех скриптов, только кроме своих скриптов
в сборку нужно включить скрипты нпм. 

Дайте, пожалуйста, советы

Мой конфиг вебпака https://jsfiddle.net/9qkwuru1/.

'use strict';

const NODE_ENV = process.env.NODE_ENV || 'development';
const webpack = require('webpack');

var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    context: __dirname,
    entry: "./table/static/table/js/settings.js",
    output: {
        path: __dirname + "/common",
        filename: "bundle.js"
    },

    watch: NODE_ENV == 'development',
    watchOptions: {
        aggregateTimeout: 100
    },

    devtool: NODE_ENV == 'development' ? 'source-map' : null,

    resolve: {
        moduleDirectories: ['node_modules'],
        extension: ['', '.js', '.styl']
    },

    resolveLoader: {
        moduleDirectories: ['node_modules'],
        moduleTemplates: ['*-loader'],
        extension: ['', '.js'   ]
    },

    module: {
      loaders: [{
          test: /\.js$/,
          loader: 'babel',
          exclude: [
            /(node_modules|bower_components)/
          ],
          query: {
            presets: ['es2015']
          }
        }, {
          test: /\.jade$/,
          loader: 'jade'
      }, {
          test: /\.css$/,
          loader: ExtractTextPlugin.extract({
              fallbackLoader: "style-loader",
              loader: "css-loader"
          })
      }, {
          test: /\.styl$/,
          loader: 'style!css!autoprefixer?browsers=last 2 version!stylus?resolve url'
      }, {
          test: /\.(png|jpg|svg)/,
          loader: 'file?name=[path][name].[ext]'
      }]
    },

    plugins: [
        new webpack.NoErrorsPlugin(),
        new webpack.DefinePlugin({
            NODE_ENV: JSON.stringify(NODE_ENV)
        }),
        new webpack.ProvidePlugin({}),
        new ExtractTextPlugin({
            filename: "bundle.css"
        })
    ]
};

if (NODE_ENV == 'production') {
    module.exports.plugins.push(
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false,
                drop_console: true,
                unsafe: true
            }
        })
    )
}

    


Ответы

Ответ 1



Мне приходилось решать такую задачу в одном из боевых проектов. Для этого я использовал функцию glob, которая собирает все файлы по маске. https://www.npmjs.com/package/glob И обертку для нее, которая позволяет задавать несколько таких масок массивом: https://www.npmjs.com/package/glob-all Она довольно простая, не смотрите что звезд не очень много. Ставим этот пакет (сам glob он вытянет зависимостью): npm install glob-all --save-dev В вебпак конфиге: var glob = require("glob-all"); После этого выдаем точкам входа результат, например так: entry: { yourAwesomeEntryPoint: glob.sync([ "./someFolder/*.js", "./anotherFolder/*.js" ]), Соответственно маски могут задаваться довольно хитро, в том числе регуляркой, подробнее в документации к пакетам. В моем случае этого хватило.

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

Как подружить wxWidgets и CLion (Windows + mingw-w64)?

#c #cmake #сборка #clion #wxwidgets


Хочу сделать GUI приложение и выбрал для этого Си (без ++) и wxWidgets. Скачал с
офф.сайта установщик, поставил (Установился в C:\wxWidgets-3.1.1, но я кинул рядом
с исходниками папку с библиотекой в папке wx есть файл, который просится в коде).

 

Думал, что на этом всё, но нет, при попытке компиляции вылазит ошибка, что нет библиотеки.

Ошибка:


  "C:\Program Files\JetBrains\CLion 2018.1.5\bin\cmake\bin\cmake.exe" --build C:\Users\Timoshka-WIN10\Documents\CLionProjects\GuiTEST\cmake-build-debug
--target GuiTEST -- -j 1
      [ 50%] Building C object CMakeFiles/GuiTEST.dir/main.c.obj
      C:\Users\Timoshka-WIN10\Documents\CLionProjects\GuiTEST\main.c:3:10: fatal
error: wx/wxprec.h: No such file or directory
       #include 
                ^~~~~~~~~~~~~
      compilation terminated.
      mingw32-make.exe[3]: * [CMakeFiles\GuiTEST.dir\build.make:62: CMakeFiles/GuiTEST.dir/main.c.obj]
Error 1
      mingw32-make.exe2:  [CMakeFiles\Makefile2:67: CMakeFiles/GuiTEST.dir/all] Error 2
      mingw32-make.exe1:  [CMakeFiles\Makefile2:79: CMakeFiles/GuiTEST.dir/rule] Error 2
      mingw32-make.exe: * [Makefile:117: GuiTEST] Error 2


CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(GuiTEST C)

set(CMAKE_C_STANDARD 11)

add_executable(GuiTEST main.c)

target_include_directories ( GuiTEST PUBLIC
        $< BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}libs/wxWidgets-3.1.1/include >
        $< INSTALL_INTERFACE:libs/wxWidgets-3.1.1/include >  # /include/mylib
        )


Код с офф.сайта wxWidgets

// wxWidgets "Hello World" Program
// For compilers that support precompilation, includes "wx/wx.h".
#include 
#ifndef WX_PRECOMP
    #include 
#endif
class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};
class MyFrame : public wxFrame
{
public:
    MyFrame();
private:
    void OnHello(wxCommandEvent& event);
    void OnExit(wxCommandEvent& event);
    void OnAbout(wxCommandEvent& event);
};
enum
{
    ID_Hello = 1
};
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
    MyFrame *frame = new MyFrame();
    frame->Show(true);
    return true;
}
MyFrame::MyFrame()
    : wxFrame(NULL, wxID_ANY, "Hello World")
{
    wxMenu *menuFile = new wxMenu;
    menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
                     "Help string shown in status bar for this menu item");
    menuFile->AppendSeparator();
    menuFile->Append(wxID_EXIT);
    wxMenu *menuHelp = new wxMenu;
    menuHelp->Append(wxID_ABOUT);
    wxMenuBar *menuBar = new wxMenuBar;
    menuBar->Append(menuFile, "&File");
    menuBar->Append(menuHelp, "&Help");
    SetMenuBar( menuBar );
    CreateStatusBar();
    SetStatusText("Welcome to wxWidgets!");
    Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello);
    Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT);
    Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT);
}
void MyFrame::OnExit(wxCommandEvent& event)
{
    Close(true);
}
void MyFrame::OnAbout(wxCommandEvent& event)
{
    wxMessageBox("This is a wxWidgets Hello World example",
                 "About Hello World", wxOK | wxICON_INFORMATION);
}
void MyFrame::OnHello(wxCommandEvent& event)
{
    wxLogMessage("Hello world from wxWidgets!");
}


Говорят, что надо что-то подшаманить в CMakeLists.txt, или добавить target_include_directories,
но в первом случае вроде под Ubuntu и не понятно, а во втором и по официальному мануалу
для CMake тоже ничего не понятно :).
    


Ответы

Ответ 1



В CMake есть команда find_package. Поиск wxWidgets должен выглядеть так : cmake_minimum_required(VERSION 2.8) project(MySuperProgram) find_package(wxWidgets REQUIRED) add_executable(${PROJECT_NAME} "main.cpp") target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17) target_link_libraries(${PROJECT_NAME} ${wxWidgets_LIBRARIES}) target_compile_definitions(${PROJECT_NAME} PRIVATE ${wxWidgets_DEFINITIONS}) target_include_directories(${PROJECT_NAME} PRIVATE ${wxWidgets_INCLUDE_DIRS}) У меня linux и этого вполне хватает чтобы скомпилировать проект Hello World. Я wxWidgets не использовал. Но по описаниям он написан на C++. Даже в вашем примере код C++. Не уверен что будет легко использовать wxWidgets с языком С.

Ответ 2



target_include_directories( GuiTEST PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/libs/wxWidgets-3.1.1/include

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

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

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


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


Ответы

Ответ 1



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

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

Как правильно импортировать модуль JavaScript

#javascript #webpack #сборка


В проекте имеется директория frontend следующей структуры:

├── common
    ├── static
           ├── css
           ├── js
                └── common.js
├── node_modules
├── package.json
├── app
    ├── static
           ├── css
           ├── js
                └── script1.js
                └── script2.js
└── webpack.config.js


Классы и некоторые методы, которые я определил в common.js, мне нужны в script1.js
и script2.js. Я их импортировал как

 import './common/static/js/common.js'
 import { Class1, Class2 } from './common/static/js/common.js'


Но при сборке webpack --display-error-details сообщает об отсутвующем модуле

ERROR in ./app/static/app/js/settings.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./common/static/js/common.js
in      .../frontend/app/static/table/js resolve file

 .../frontend/app/static/table/js/common/static/js/common.js doesn't exist


То есть webpack ищет файл в том же каталоге, где располгается вызывающий скрипт,
а не каталог frontend.

Я понимаю, что могу задать инструкцию импорта вида ../../../../../../script.js, но
это выглядит не очень.

Можно сделать так, чтобы webpack искал относительно заданного мной каталога, в данном
случае frontend? 

Сейчас часть конфига с resolve выглядит так:

resolve: {
        moduleDirectories: ['node_modules'],
        extension: ['', '.js', '.styl']
},




Дополнение. Импорт прошел успешно только после того, как добавил в конфиг директорию
с импортируемым скриптом:

resolve: {
    root: [
        path.resolve('./common/static/js'),
    ],
    moduleDirectories: ['node_modules'],
    extension: ['', '.js', '.styl']
},


Почему добавляется в качестве корня этот каталог и не добавляется каталог, в котором
лежит конфиг?



Ошибка исправлена - неправильно записывал импорты.  Настройки вебпака из ответа Утки

 resolve: {
    root: [
        path.resolve(__dirname),
    ],
    moduleDirectories: ['node_modules'],
    extension: ['', '.js', '.styl']
},


Поправил импорт

import { capitalizeFirstLetter, formatString } from 'common/static/js/common.js';
import { elementByClass, elementById } from 'common/static/js/common.js'

    


Ответы

Ответ 1



Для webpack 1 (то есть текущего стабильного документированного) нужно добавить root в секцию resolve: var path = require('path'); resolve: { root: [ path.resolve('yourRoot') ] }, yourRoot - расположение желаемого корня. Например текущую директорию для webpack.config.js можно взять так: path.resolve(__dirname) path - родной нодовский модуль, ставить отдельно не надо.

CMake не видит компилятора

#cpp #c #g++ #cmake #сборка


Поставил CMake (без CLang), добавил в переменную path путь к cmake-3.9.2/bin.

cmake -version 


работает. 

Есть CMakeLists.txt файл

#cmake

cmake_minimum_required(VERSION 3.5)

project(concentration)

option(set_clang "set clang as default compiler" 0)
option(set_gpp "set g++ as default compiler" 0)
option(cros_compile "cros compile for win32" 0)

if(${UNIX})
    message(STATUS "Unix system")
elseif(${WIN32})
    message(WARNING "Work is not guaranted")
else()
    message(FATAL_ERROR "System not supported")
endif()

if(set_gpp)
    set(CMAKE_CXX_COMPILER g++)
endif()
if(set_clang)
    set(CMAKE_CXX_COMPILER clang++)
endif()
if(cros_compile)
    set(PROJECT_NAME ${PROJECT_NAME}.exe)
    set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++-posix)
    set(CMAKE_CXX_FLAGS "-static-libstdc++ -static-libgcc")
endif()

message(STATUS "Project " ${PROJECT_NAME})
message(STATUS "cxx compiler " ${CMAKE_CXX_COMPILER})

add_definitions(-Wall -std=c++14)

include_directories(include)

set(MAIN_SRC sources/main.cpp)
file(GLOB CONCENTRATION_SRC "sources/concentration/*.cpp")

if(cros_compile)
    find_package(PDCurses REQUIRED)
else()
    find_package(Curses REQUIRED)
endif()

include_directories(${CURSES_INCLUDE_DIR})

add_executable(${PROJECT_NAME} ${MAIN_SRC} ${CONCENTRATION_SRC})

target_link_libraries(${PROJECT_NAME} ${CURSES_LIBRARIES})


в общем когда запускаю командами

cmake
cmake -Dset_gpp=1 


CMake пишет:


-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
CMake Error at CMakeLists.txt:5 (project):
  The CMAKE_C_COMPILER:

    cl

  is not a full path and was not found in the PATH.

  To use the NMake generator with Visual C++, cmake must be run from a shell
  that can use the compiler cl from the command line.  This environment is
  unable to invoke the cl compiler.  To fix this problem, run cmake from the
  Visual Studio Command Prompt (vcvarsall.bat).

  Tell CMake where to find the compiler by setting either the environment
  variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
  the compiler, or to the compiler name if it is in the PATH.


CMake Error at CMakeLists.txt:5 (project):
  The CMAKE_CXX_COMPILER:

    cl

  is not a full path and was not found in the PATH.

  To use the NMake generator with Visual C++, cmake must be run from a shell
  that can use the compiler cl from the command line.  This environment is
  unable to invoke the cl compiler.  To fix this problem, run cmake from the
  Visual Studio Command Prompt (vcvarsall.bat).

  Tell CMake where to find the compiler by setting either the environment
  variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
  to the compiler, or to the compiler name if it is in the PATH.


-- Configuring incomplete, errors occurred!
See also "../CMakeFiles/CMakeOutput.log".
See also "../CMakeFiles/CMakeError.log".



Путь к компилятору есть в path. g++ команда работает. Постоянно компилирую с командной
строки. Пробовал в CmakeLists.txt указывать явный путь к g++. Все равно не помогает.
Все пути к файлам - латиница.

В общем, нужна помощь!
    


Ответы

Ответ 1



В Windows, судя по исходникам, CMake по дефолту (если генератор не указан явно) пробует найти (по записям в реестре) самую свежую версию Visual Studio, а если не находит, использует NMake. Таким образом, если у вас установлена Студия (или просто остался мусор в реестре, в результате некорректного удаления студии или по другим, гораздо более серьезным причинам), то CMake будет делать проект под самую свежую из установленных Студий. Чтобы явно указать нужный вам генератор, используйте ключик -G: cmake -G "MinGW Makefiles"

суббота, 30 ноября 2019 г.

Чем плохи большие размеры исполняемых файлов?

#cpp #оптимизация #сборка #компоновщик


Уже не раз видел ответы людей по типу: 


  -О3 генерирует быстрый, но раздутый исполняемый файл





  LTO помогает этот раздутый код уменьшить





  Шаблоны С++ приводят к распуханию исполняемого файла, это плохо


или 


  Используй компоновщик gold вместо gnu-ld, он собирает меньший по размеру исполняемый
файл... 


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

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


Ответы

Ответ 1



Для начала предлагаю отвлечься от слова "исполняемый" и рассмотреть просто файл. Что значит большой размер? Файл потребует больше места для хранения, он дольше будет копироваться или как-то иначе обрабатываться, когда речь идет об обработке его содержимого, а не просто имени или даты создания. В таких случаях часто прибегают к механизмам дополнительного сжатия информации, проще говоря, архивированию. Это уменьшит размер и время копирования, но для последующей обработки, вероятнее всего, придется выполнить распаковку, что может в итоге даже увеличить время обработки по сравнению с несжатым файлом. Теперь, чем отличается исполняемый файл от обычного? Он так или иначе содержит код, набор инструкций, которые должен выполнить (обработать) процессор. Понятно, что размер программы зависит от предоставляемого функционала, и наращивание логики приведет к увеличению размера. В большинстве случаев это не является проблемой, так как диски становятся всё больше, память и процессоры быстрее, а архитектурные решения опираются на декомпозицию: разделение кода на модули/библиотеки и подгрузку кода по мере необходимости. Но в некоторых ситуациях, например, в микроконтроллерах ресурсы серьезно ограничены и там идет борьба за размер, и использование разных техник оптимизации. Кстати, для исполняемых файлов тоже существуют архиваторы, один из них, это UPX.

Ответ 2



-О3 генерирует быстрый, но раздутый исполняемый файл По нынешним временам для большинства задач скорость более критична чем размер файла. Если код быстрый (все инлайн подстановки выполнены, многие циклы развернуты, все инварианты вынесены из циклов) то больше ничего от кода и не надо. Ребята, которые пишут оптимизаторы, не зря едят свои гамбургеры. Если нужен БЫСТРЫЙ код, то следует применять оптимизацию. шаблоны c++ приводят к распуханию исполняемого файла Это утверждение более чем спорно. Если шаблоны нужны в данной задаче, то они никак не увеличивают код по сравнению с ручным переписыванием классов с незначительными изменениями. В любом случае инстанцирование шаблона в С++ вполне прозрачно и всегда понятно, во что компилятор развернет шаблон. UPD1: Для микроконтроллеров теоретически есть проблема размера бинарника но и там память дешевле чем скорость даже более чем на десктопах и серверах. Так что если на микроконтроллере бинарник не влезает в память, то это показатель плохого дизайна системы. Всегда проще и дешевле поставить лишний чип памяти, а вот добавить лишних терафлопсов это уже совсем другие деньги.

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

Что включать в Docker-образ

Имеется веб-сайт на Django, на боевом сервере для запуска использую связку uWSGI/Nginx, локальная разработка - virtualenv/dev-сервер Django
Из некоторых вопросов, которые задал на SO:
Распространение Docker-образов Запуск Docker-образов на боевом сервере Запуск сайта из Docker-образа VS запуск c традиционными средствами (uWSGI, Nginx, Apache)
появилось еще пара.
Что включать в образ Docker?
Мы имеем production-версию и developer-версию. Как понимаю, в репозиториях распространяют production.
Имеет ли смысл создавать docker-образ для developer-версии (применительно ко мне, код проекта и виртуальное окружение virtualenv)? Или разработчику достаточно только кода из репозитория, чтобы начать разработку?
Где создают docker-образ production-версии?
На боевом сервере имеется проект, который работает на указанной связке - uwsgi/nginx/упаковщик с production-настройками. Собирать образ я должен на боевом сервере?


Ответ

Не должно быть понятия production и non-production версия образа. Разработчики, тестировщики, эксплуатационники и все остальные должны использовать одну и туже версию образа.
Процесс разработки может быть устроен совершенно по разному, но если используется docker-образ (например, сервер разрабатываемый другой группой) в качестве внешней зависимости, то он должен браться из того же источника, что и для других нужд - тестирование, эксплуатация и т.п.
Как, где и чем создают docker-образы?
Процесс изготовления образа должен быть полностью автоматизирован, что бы избежать ошибок и сделать процесс повторяемым.
Приблизительно процесс изготовления образа выглядит так (я опускаю некоторые шаги):
Разработчик дописал код и протестировал его локально, в том числе и сборку образа. Разработчик заливает код в систему контроля версий. Робот собирает проект и создает артефакты для развертывания (мнифицирует все, объединяет в общий пакет и т.п.).
Необязательный шаг - артефакты помещаются в хранилище. Робот собирает docker-образ.
Необязательный шаг - робот подписывает образ. Робот заливает образ в реестр.
Если нет специфических требовани, то для управления процессом создания можно использовать любой Continuous Integration сервер - Jenkins, TeamCity, Bamboo и т.д. У них у всех есть соответсвующие плагины или можно написать простые шел-скрипты и создавать образы стандартной командой docker build
Что включать в docker-образ?
Сложно дать однозначный ответ на этот вопрос, так как многое зависит от типа образа и личных предпочтений. Я напишу как бы я поступил с сервером на Django
Я мало работал с Django, так что поправьте меня, если я говорю что-то несоответствующее действительности.
Если проект только начинается и нагрузка на сервис будет маленькая, то я бы поместил все (кроме БД) в один образ. Т.е. образ будет содержать:
Python фиксированной версии установленный как системный (без virtualenv и пр) nginx/Apache фиксированных версий с нужными настройками собственно ваше приложение, взятое как артефакт для развертывания и развернутое внутри образа
БД либо в отдельный образ, либо на отдельный сервер без использования контейнерезации. Если БД идёт отдельным образом, то важно позаботится о сохранении данных на внешний (по отношению к контейнеру) раздел диска. В противном случае данные будут утеряны при перезапуске контейнера.
Если нагрузка будет значительная и есть много статических страниц, то я бы сделал несколько образов:
Образ со статическими страницами
nginx/Apache статическая часть вашего приложения Образ с динамической частью
Python часть вашего приложения (Django) Образ балансировщиком (необязательный)
nginx/HAProxy/Varnish/etc
Если проект очень большой, то возможно статическую и динамическую часть делают разные команды и в этом случае они и буду отвечать за подготовку Dockerfile к своей части проекта.

суббота, 23 марта 2019 г.

Зачем нужен maven?

Здравствуйте, очень хотелось бы узнать, много пересмотрел и перечитал, но не могу понять. Зачем нужен Maven, если есть IDE - Eclipse, Netbeans и т.д.? В чем его преимущество по сборкам, если и IDE справляются?


Ответ

Не совсем корректный вопрос, нельзя сравнивать Maven и среды разработки. C Maven можно работать и без сред разработки. Зачем нужен? Для управления зависимостями, для сборки проектов, и для кучи всего остального полезного. К примеру, ты пишешь большой проект и используешь в нем много технологий, к примеру, Hibernate, JUnit. Возникает вопрос как подключить все библиотеки? Ответ прост - просто прописать зависимости в pom.xml, а maven их скачает за тебя. Затем возможна такая ситуация, ты хочешь показать проект другу, отправляешь ему, но вот проблема, если это не проект Maven, то твоему другу придется скачивать библиотеки, чтобы проект заработал, а так за него это сделает Maven.С ростом твоих проектов - ты сам оценишь достоинства Maven. IDE справляются - а если нет IDE на твоем компьютере?Что будешь делать? На помощь приходит Maven, он кроссплатформенный и для работы с ним достаточно командной строки.

пятница, 1 марта 2019 г.

Andoid. Debuggable приложение тормозит

Условия:
Я работаю на двух компьютерах - дома и на работе. Я собираю одно и то же приложение с опцией debuggable=true Делаю я это на одном и том же девайсе.
Проблема:
При сборке на работе приложение не тормозит ни в debug buildType (будучи debuggable), ни в release buildType. Но стоит мне собрать его дома, как в debug buildType приложение начинает тормозить на экранах с тяжелой версткой (множество 'ов). А если еще и в debug-режим войти, то просто кромешный ад! При этом в release buildType все летает на тех же самых экранах.
Вопрос: Должны ли быть включены/выключены какие-то особые настройки Android Studio, чтобы оптимизировать работу debuggable приложения? (вроде и на работе и дома ставил студию одинаково, не изменяя каких-либо важных настроек). Быть может от самого компьютера зависит скорость работы приложения на телефоне (звучит фантастически, но я уже не знаю на что думать)


Ответ

Подобное поведение может быть вызвано функцией Instant Run - она обновляет приложение в реальном времени при изменениях в коде в дебаг режиме. Это, надо полагать, требует постоянного обмена данными и их обработки, что нагружает и комп и девайс. Отключение оной может помочь.

среда, 20 февраля 2019 г.

Webpack. Сборка отдельных css и скриптов в общие файлы

Как собрать разрозненные в проекте стили/скрипты в один файл (bundle.js/bundle.css)с помощью webpack?
Проект содержит стили и скрипты для каждого приложения, которые лежат в отдельном каталоге. Папка фронтенда:
├── frontend │   ├── common │   ├── node_modules │   ├── app1 │   ├── app2 │   ├── app3 │   ├── ... │   └── webpack.config.js
Папка каждого приложения имеет одинаковую структуру, но содержит разное количество скриптов, стилей, шаблонов, который располагаются на одном уровне:
├── app │   ├── static │   │   └── app │   │   ├── css │   │   │   └── app.css │   │   └── js │   │   ├── app-detail.js │   │   └── settings.js │   └── templates │   └── app │   ├── app__element-detail.html │   ├── app.html │   ├── app__periodic-table.html │   └── app__settings.html
Как собирать все эти файлы в один?
Применительно к стилям - видел способ с extract-text-webpack-plugin, но во всех примерах показыват один и тот же сценарий - одна точка входа, стили импортированы в скрипт и из них уже собирается.
Мне же нужно просто сделать бандл, его подключу в базовом шаблоне.
Аналогичный вопрос можно задать и по сборке всех скриптов, только кроме своих скриптов в сборку нужно включить скрипты нпм.
Дайте, пожалуйста, советы
Мой конфиг вебпака https://jsfiddle.net/9qkwuru1/
'use strict';
const NODE_ENV = process.env.NODE_ENV || 'development'; const webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = { context: __dirname, entry: "./table/static/table/js/settings.js", output: { path: __dirname + "/common", filename: "bundle.js" },
watch: NODE_ENV == 'development', watchOptions: { aggregateTimeout: 100 },
devtool: NODE_ENV == 'development' ? 'source-map' : null,
resolve: { moduleDirectories: ['node_modules'], extension: ['', '.js', '.styl'] },
resolveLoader: { moduleDirectories: ['node_modules'], moduleTemplates: ['*-loader'], extension: ['', '.js' ] },
module: { loaders: [{ test: /\.js$/, loader: 'babel', exclude: [ /(node_modules|bower_components)/ ], query: { presets: ['es2015'] } }, { test: /\.jade$/, loader: 'jade' }, { test: /\.css$/, loader: ExtractTextPlugin.extract({ fallbackLoader: "style-loader", loader: "css-loader" }) }, { test: /\.styl$/, loader: 'style!css!autoprefixer?browsers=last 2 version!stylus?resolve url' }, { test: /\.(png|jpg|svg)/, loader: 'file?name=[path][name].[ext]' }] },
plugins: [ new webpack.NoErrorsPlugin(), new webpack.DefinePlugin({ NODE_ENV: JSON.stringify(NODE_ENV) }), new webpack.ProvidePlugin({}), new ExtractTextPlugin({ filename: "bundle.css" }) ] };
if (NODE_ENV == 'production') { module.exports.plugins.push( new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, drop_console: true, unsafe: true } }) ) }


Ответ

Мне приходилось решать такую задачу в одном из боевых проектов.
Для этого я использовал функцию glob, которая собирает все файлы по маске. https://www.npmjs.com/package/glob И обертку для нее, которая позволяет задавать несколько таких масок массивом: https://www.npmjs.com/package/glob-all Она довольно простая, не смотрите что звезд не очень много.
Ставим этот пакет (сам glob он вытянет зависимостью):
npm install glob-all --save-dev
В вебпак конфиге:
var glob = require("glob-all");
После этого выдаем точкам входа результат, например так:
entry: { yourAwesomeEntryPoint: glob.sync([ "./someFolder/*.js", "./anotherFolder/*.js" ]),
Соответственно маски могут задаваться довольно хитро, в том числе регуляркой, подробнее в документации к пакетам.
В моем случае этого хватило.

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

CMake не видит компилятора

Поставил CMake (без CLang), добавил в переменную path путь к cmake-3.9.2/bin
cmake -version
работает.
Есть CMakeLists.txt файл
#cmake
cmake_minimum_required(VERSION 3.5)
project(concentration)
option(set_clang "set clang as default compiler" 0) option(set_gpp "set g++ as default compiler" 0) option(cros_compile "cros compile for win32" 0)
if(${UNIX}) message(STATUS "Unix system") elseif(${WIN32}) message(WARNING "Work is not guaranted") else() message(FATAL_ERROR "System not supported") endif()
if(set_gpp) set(CMAKE_CXX_COMPILER g++) endif() if(set_clang) set(CMAKE_CXX_COMPILER clang++) endif() if(cros_compile) set(PROJECT_NAME ${PROJECT_NAME}.exe) set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++-posix) set(CMAKE_CXX_FLAGS "-static-libstdc++ -static-libgcc") endif()
message(STATUS "Project " ${PROJECT_NAME}) message(STATUS "cxx compiler " ${CMAKE_CXX_COMPILER})
add_definitions(-Wall -std=c++14)
include_directories(include)
set(MAIN_SRC sources/main.cpp) file(GLOB CONCENTRATION_SRC "sources/concentration/*.cpp")
if(cros_compile) find_package(PDCurses REQUIRED) else() find_package(Curses REQUIRED) endif()
include_directories(${CURSES_INCLUDE_DIR})
add_executable(${PROJECT_NAME} ${MAIN_SRC} ${CONCENTRATION_SRC})
target_link_libraries(${PROJECT_NAME} ${CURSES_LIBRARIES})
в общем когда запускаю командами
cmake cmake -Dset_gpp=1
CMake пишет:
-- The C compiler identification is unknown -- The CXX compiler identification is unknown CMake Error at CMakeLists.txt:5 (project): The CMAKE_C_COMPILER:
cl
is not a full path and was not found in the PATH.
To use the NMake generator with Visual C++, cmake must be run from a shell that can use the compiler cl from the command line. This environment is unable to invoke the cl compiler. To fix this problem, run cmake from the Visual Studio Command Prompt (vcvarsall.bat).
Tell CMake where to find the compiler by setting either the environment variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to the compiler, or to the compiler name if it is in the PATH.
CMake Error at CMakeLists.txt:5 (project): The CMAKE_CXX_COMPILER:
cl
is not a full path and was not found in the PATH.
To use the NMake generator with Visual C++, cmake must be run from a shell that can use the compiler cl from the command line. This environment is unable to invoke the cl compiler. To fix this problem, run cmake from the Visual Studio Command Prompt (vcvarsall.bat).
Tell CMake where to find the compiler by setting either the environment variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path to the compiler, or to the compiler name if it is in the PATH.
-- Configuring incomplete, errors occurred! See also "../CMakeFiles/CMakeOutput.log". See also "../CMakeFiles/CMakeError.log".
Путь к компилятору есть в path. g++ команда работает. Постоянно компилирую с командной строки. Пробовал в CmakeLists.txt указывать явный путь к g++. Все равно не помогает. Все пути к файлам - латиница.
В общем, нужна помощь!


Ответ

В Windows, судя по исходникам, CMake по дефолту (если генератор не указан явно) пробует найти (по записям в реестре) самую свежую версию Visual Studio, а если не находит, использует NMake.
Таким образом, если у вас установлена Студия (или просто остался мусор в реестре, в результате некорректного удаления студии или по другим, гораздо более серьезным причинам), то CMake будет делать проект под самую свежую из установленных Студий.
Чтобы явно указать нужный вам генератор, используйте ключик -G:
cmake -G "MinGW Makefiles"

вторник, 5 февраля 2019 г.

Как подружить wxWidgets и CLion (Windows + mingw-w64)?

Хочу сделать GUI приложение и выбрал для этого Си (без ++) и wxWidgets. Скачал с офф.сайта установщик, поставил (Установился в C:\wxWidgets-3.1.1, но я кинул рядом с исходниками папку с библиотекой в папке wx есть файл, который просится в коде).

Думал, что на этом всё, но нет, при попытке компиляции вылазит ошибка, что нет библиотеки.
Ошибка:
"C:\Program Files\JetBrains\CLion 2018.1.5\bin\cmake\bin\cmake.exe" --build C:\Users\Timoshka-WIN10\Documents\CLionProjects\GuiTEST\cmake-build-debug --target GuiTEST -- -j 1 [ 50%] Building C object CMakeFiles/GuiTEST.dir/main.c.obj C:\Users\Timoshka-WIN10\Documents\CLionProjects\GuiTEST\main.c:3:10: fatal error: wx/wxprec.h: No such file or directory #include ^~~~~~~~~~~~~ compilation terminated. mingw32-make.exe[3]: * [CMakeFiles\GuiTEST.dir\build.make:62: CMakeFiles/GuiTEST.dir/main.c.obj] Error 1 mingw32-make.exe2: [CMakeFiles\Makefile2:67: CMakeFiles/GuiTEST.dir/all] Error 2 mingw32-make.exe1: [CMakeFiles\Makefile2:79: CMakeFiles/GuiTEST.dir/rule] Error 2 mingw32-make.exe: * [Makefile:117: GuiTEST] Error 2
CMakeLists.txt
cmake_minimum_required(VERSION 3.10) project(GuiTEST C)
set(CMAKE_C_STANDARD 11)
add_executable(GuiTEST main.c)
target_include_directories ( GuiTEST PUBLIC $< BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}libs/wxWidgets-3.1.1/include > $< INSTALL_INTERFACE:libs/wxWidgets-3.1.1/include > # /include/mylib )
Код с офф.сайта wxWidgets
// wxWidgets "Hello World" Program // For compilers that support precompilation, includes "wx/wx.h". #include #ifndef WX_PRECOMP #include #endif class MyApp : public wxApp { public: virtual bool OnInit(); }; class MyFrame : public wxFrame { public: MyFrame(); private: void OnHello(wxCommandEvent& event); void OnExit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); }; enum { ID_Hello = 1 }; wxIMPLEMENT_APP(MyApp); bool MyApp::OnInit() { MyFrame *frame = new MyFrame(); frame->Show(true); return true; } MyFrame::MyFrame() : wxFrame(NULL, wxID_ANY, "Hello World") { wxMenu *menuFile = new wxMenu; menuFile->Append(ID_Hello, "&Hello...\tCtrl-H", "Help string shown in status bar for this menu item"); menuFile->AppendSeparator(); menuFile->Append(wxID_EXIT); wxMenu *menuHelp = new wxMenu; menuHelp->Append(wxID_ABOUT); wxMenuBar *menuBar = new wxMenuBar; menuBar->Append(menuFile, "&File"); menuBar->Append(menuHelp, "&Help"); SetMenuBar( menuBar ); CreateStatusBar(); SetStatusText("Welcome to wxWidgets!"); Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello); Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT); Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT); } void MyFrame::OnExit(wxCommandEvent& event) { Close(true); } void MyFrame::OnAbout(wxCommandEvent& event) { wxMessageBox("This is a wxWidgets Hello World example", "About Hello World", wxOK | wxICON_INFORMATION); } void MyFrame::OnHello(wxCommandEvent& event) { wxLogMessage("Hello world from wxWidgets!"); }
Говорят, что надо что-то подшаманить в CMakeLists.txt, или добавить target_include_directories, но в первом случае вроде под Ubuntu и не понятно, а во втором и по официальному мануалу для CMake тоже ничего не понятно :).


Ответ

target_include_directories( GuiTEST PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/libs/wxWidgets-3.1.1/include

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

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

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


Ответ

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

суббота, 27 октября 2018 г.

Как правильно импортировать модуль JavaScript

В проекте имеется директория frontend следующей структуры:
├── common ├── static    ├── css    ├── js      └── common.js ├── node_modules ├── package.json ├── app ├── static    ├── css    ├── js      └── script1.js └── script2.js └── webpack.config.js
Классы и некоторые методы, которые я определил в common.js, мне нужны в script1.js и script2.js. Я их импортировал как
import './common/static/js/common.js' import { Class1, Class2 } from './common/static/js/common.js'
Но при сборке webpack --display-error-details сообщает об отсутвующем модуле
ERROR in ./app/static/app/js/settings.js Module not found: Error: Cannot resolve 'file' or 'directory' ./common/static/js/common.js in .../frontend/app/static/table/js resolve file
.../frontend/app/static/table/js/common/static/js/common.js doesn't exist
То есть webpack ищет файл в том же каталоге, где располгается вызывающий скрипт, а не каталог frontend
Я понимаю, что могу задать инструкцию импорта вида ../../../../../../script.js, но это выглядит не очень.
Можно сделать так, чтобы webpack искал относительно заданного мной каталога, в данном случае frontend?
Сейчас часть конфига с resolve выглядит так:
resolve: { moduleDirectories: ['node_modules'], extension: ['', '.js', '.styl'] },

Дополнение. Импорт прошел успешно только после того, как добавил в конфиг директорию с импортируемым скриптом:
resolve: { root: [ path.resolve('./common/static/js'), ], moduleDirectories: ['node_modules'], extension: ['', '.js', '.styl'] },
Почему добавляется в качестве корня этот каталог и не добавляется каталог, в котором лежит конфиг?

Ошибка исправлена - неправильно записывал импорты. Настройки вебпака из ответа Утки
resolve: { root: [ path.resolve(__dirname), ], moduleDirectories: ['node_modules'], extension: ['', '.js', '.styl'] },
Поправил импорт
import { capitalizeFirstLetter, formatString } from 'common/static/js/common.js'; import { elementByClass, elementById } from 'common/static/js/common.js'


Ответ

Для webpack 1 (то есть текущего стабильного документированного) нужно добавить root в секцию resolve
var path = require('path');
resolve: { root: [ path.resolve('yourRoot') ] },
yourRoot - расположение желаемого корня. Например текущую директорию для webpack.config.js можно взять так: path.resolve(__dirname)
path - родной нодовский модуль, ставить отдельно не надо.