воскресенье, 1 мая 2011 г.

Настройка CodeBlocks для компиляции wxWidgets / Win32 приложений для Windows компилятором Mingw32 из под Linux/FreeBSD

Установка CodeBlocks из портов:

portinstall codeblocks


Запускаем CodeBlocks, далее меню "Settings" -> "Compiler and Debugger" -> "Selected compiler"
"GNU GCC Compiler" -> "Copy"
задаем имя компилятора "MinGW32 Compiler"

Для этого компилятора задаём:
в "#defines"

WINVER=0x0400
__WIN95__
__GNUWIN32__
STRICT
HAVE_W32API_H
__WXMSW__
__WINDOWS__

в "Toolchain executables" пропишем
"Compiler's installation directory" ~/mingw-cross-env/usr или что там у вас.








"C compiler:"i686-pc-mingw32-gcc
"C++ compiler:"i686-pc-mingw32-g++
"Linker for dynamic libs:"i686-pc-mingw32-g++
"Linker for static libs:" i686-pc-mingw32-ar
"Debugger:"i686-pc-mingw32-gdb
"Resorce compiler:"i686-pc-mingw32-windres
"Make program:"make

По поводу i686-pc-mingw32-gdb, надо создать скрипт ~/mingw-cross-env/usr/bin/i686-pc-mingw32-gdb

cd ~/mingw-cross-env
make gdb
touch ~/mingw-cross-env/usr/bin/i686-pc-mingw32-gdb
echo '#!/bin/csh' >> ~/mingw-cross-env/usr/bin/i686-pc-mingw32-gdb
echo 'wine ~/mingw-cross-env/usr/i686-pc-mingw32/bin/gdb.exe "$@"' >> ~/mingw-cross-env/usr/bin/i686-pc-mingw32-gdb
chmod +x ~/mingw-cross-env/usr/bin/i686-pc-mingw32-gdb



Да и ещё, некоторые общие настройки, хотя и без них wxWidgets приложение соберется, прописать в
"Other Linker Options":
-lstdc++
-lgcc
-lodbc32
-lwsock32
-lwinspool
-lwinmm
-lshell32
-lcomctl32
-lctl3d32
-lodbc32
-ladvapi32
-lodbc32
-lwsock32
-lopengl32
-lglu32
-lole32
-loleaut32
-luuid

Прописать в "Search directories"
Для Compiler путь к include: ~/mingw-cross-env/usr/i686-pc-mingw32/include
Для Linker путь к lib: ~/mingw-cross-env/usr/i686-pc-mingw32/lib
Для Resource compiler: ~/mingw-cross-env/usr/i686-pc-mingw32/include

Жмём "OK"

Из под su, делал так:
ln -s /usr/local/bin/wine /usr/local/bin/wine-auto

При создании нового проекта, надо выбирать "MinGW32 Compiler"
Для новых wxWidgets проектов надо прописывать:
В "Project build options" пропишем
в "Other options":

`i686-pc-mingw32-wx-config --cxxflags`


в "Other linker options:"

`i686-pc-mingw32-wx-config --libs`



Если использовать мастер для создания проекта, то надо wx-config заменить на i686-pc-mingw32-wx-config, для этого можно открыть Ваш файл проекта CodeBlocks (*.cbp) в обычном текстовом редакторе, например, gedit и произвести замену.

Имеются некоторые проблемы при запуске программ после сборки из CodeBlocks, но в общем можно запустить с отладчиком, правда CodeBlocks 10.05 может "рухнуть", было один раз.

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

суббота, 30 апреля 2011 г.

Компилируем wxWidgets приложение для Windows из под FreeBSD

Можно скомпилировать приложение minimal из примеров, поставляемых вместе с wxWidgets.
Использовать будем mingw-cross-env, да к стати из портов можно установить mercurial, чтоб установить последнюю версию mingw-cross-env для этого запускаем:

hg clone http://hg.savannah.nongnu.org/hgweb/mingw-cross-env

Чтоб добыть обновления, запускаем:

hg pull -u


В общем после установки wxwidgets, т.е. после выполнения команд:

cd mingw-cross-env
gmake wxwidgets


В директории с кодом простого wxWidgets приложения выполним:

i686-pc-mingw32-g++ minimal.cpp -o minimal.exe `i686-pc-mingw32-wx-config --cxxflags --libs`

В текущей директории появляется minimal.exe, правда его размер несколько впечатляет почти 7 Мбайт. Можно его уменьшить командой:

i686-pc-mingw32-strip minimal.exe

Почти в два раза.

wine minimal.exe

При записке minimal.exe под Windows 98 , а также wine, при условии, что там в настройках (команда winecfg) стоит Windows 98, может вылести сообщение "wxWidgets Fatal Error\n This program uses Unicode and requires Windows NT/2000/XP ...". Ничего страшного, можно просто перекомпилировать minimal.cpp без поддержки Unicode.

i686-pc-mingw32-g++ minimal.cpp -o minimal.exe `i686-pc-mingw32-wx-config -nounicode --cxxflags --libs`


Об опциях i686-pc-mingw32-wx-config можно узнать командой:

i686-pc-mingw32-wx-config

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

суббота, 23 апреля 2011 г.

Компиляция для Windows из под FreeBSD

Ставил mingw32 из портов, результат не очень.
Но вот набрел на страницу http://mingw-cross-env.nongnu.org
Сделал:
В FreeBSD должно быть установлено: automake111 autoconf268 bash bison cmake flex gmake gsed intltool libtool openssl patch perl p5-XML-Parser pkg-config scons unzip wget yasm
И ещё wine для проверки работоспособности кода.

0. cd ~/mingw32
1. wget https://bitbucket.org/vog/mingw-cross-env/downloads/mingw-cross-env-2.20.tar.gz
2. tar -xzvf mingw-cross-env-2.20.tar.gz
3. cd mingw-cross-env-2.20
4. gmake download-gcc
Возможны проблемы с загрузкой этой командой, но можно и скачать обычным способом. То, что не сможет через скрипт скачать, можно подсмотреть в папке pkg, потестив архивы, можно ещё подсмотреть откуда качает в директории src , найдя соответствующий .mk файл
5. gmake gcc
можно приписать и другие порты после gcc, например, gmake gcc gdb и т.д.
6. редактирую ~/.cshrc , добавляю строку :
setenv PATH ~/mingw/mingw-cross-env-2.20/bin:$PATH
так как использую SHELL=csh,
для SHELL=bash в файле ~/.profile можно прописать:
export PATH = ~/mingw/mingw-cross-env-2.20/bin:$PATH
7. Компилить прогу написанную на Си можно так
i686-pc-mingw32-gcc -o main.exe main.c
8. А, запускать так
wine main.exe

вторник, 15 марта 2011 г.

Отображение кириллических символов в консоли

1. Вариант
Использовать широкие символы
Редактор кода настраивается на ввод символов в кодировке UTF-8
Settings -> Editor… -> General Settings -> Other settings -> Encoding и выбрать UTF-8.
Теперь в тексте программы один символ кодируется двумя байтами, тип которого соответствует wchar_t (тип данных стандарта ANSI/ISO C для представления широких символов). Теперь в программе надо использовать функции, которые умеют обрабатывать wchar_t символы и корректно выполнять ввод/вывод. Обычно имена функций работающих с wchat_t начинаются с символа ‘w’, стоящим перед именем аналогичной функции, но работающей с char, например,
int wprintf( const wchar_t *format [, argument]... ) ; /*аналогична printf */
int wscanf( const wchar_t *format [, argument]... ) ; /* scanf */

В Windows API, тип wchar_t имеет размер 16 бит.
В GNU/Linux тип wchar_t имеет размер 32 бита.

Пример:
/*Компилятор MinGW*/
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main()
{
setlocale(0,".866");/*Локаль, без этой строки не будет работать*/
wprintf(L"Привет!\n"); /*L – указываем, что используются широкие символы в строке*/
return 0;
}

2. Вариант
Использовать Win32Api функцию CharToOem
Текст программы имеет кодировку WINDOWS-1251 или ANSI, функция CharToOem вызывается обычно перед выводом в консоль какого-либо текста с кириллическими символами.

Пример:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main()
{
char s[] = "Текст";
CharToOem(s,s);/*Перекодируем s, после этого вызова s меняет своё значение*/
printf("%s",s);
return 0;
}

3. Вариант
Использование шрифта Lucida Console в консоли
// установить вручную шрифт Lucida Console в свойствах окна консоли
// и запомнить это для всех окон с этим именем
// записать в начале программы строку
#include <windows.h>
// записать в начале функции main ()
// две следующих строки
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

4. Вариант
Использовать опций компилятора для перекодировки текста программы из UTF-8 в CP866. Понятно, что можно использовать и другое направление перекодировки, типа WINDOWS-1251 в CP866. В консоли должна быть доступна команда iconv.
В командной строке делаем, например, так
gcc -finput-charset=UTF-8 -fexec-charset=CP866 main.c -o main

В CodeBlocks можно прописать эти опции в параметры компиляции для проекта
Project -> Build options -> Compiler settings -> Other options
Записываем строку:
-finput-charset=UTF-8 -fexec-charset=CP866

5. Вариант
Если используется компилятор от Microsoft (cl.exe), то достаточно прописать только локаль, строка в функции main():
setlocale(0,””);

пятница, 19 ноября 2010 г.

Вопрос претенденту на вакансию "Программист C++"

На нескольких сайтах, предлагающих вакансию программиста C++, встречаются одни и те же вопросы, например, на сайте вакансий yandex. Один из них такой:
Перечислите все проблемы, которые вы видите в данном коде:


1 class Foo
2 {
3 public:
4 Foo(int j) { i=new int[j]; }
5 ~Foo() { delete i; }
6 private:
7 int* i;
8 };
9
10 class Bar: Foo
11 {
12 public:
13 Bar(int j) { i=new char[j]; }
14 ~Bar() { delete i; }
15 private:
16 char* i;
17 };
18
19
20 void main()
21 {
22 Foo* f=new Foo(100);
23 Foo* b=new Bar(200);
24 *f=*b;
25 delete f;
26 delete b;
27 }



В результате медитации, получил следующий, несовершенный код, но все же отражающий моё понимание проблем:

1 class Bar;//Добавил, чтоб в классе Foo использовать имя класса Bar
2
3 class Foo
4 {
5 public:
6 Foo(int j)
7 {
8 i=new int[j];
9 }
10 Foo() {} //Добавил, т.к. нужен конструктор по умолчанию, если бы Foo(int),
» небыло, то он бы был сгенерирован компилятором

11 ~Foo()
12 {
13 delete[] i; //Изменил, добавив [], а то удалять будет не весь массив, а
» только первый элемент массива с индексом 0, т.е. получим утечку памяти

14 }
15
16 Foo operator=(const Bar& r_)//Добавил оператор присваивания, и по идее надо
» делать глубокое копирование по членам, но для этого обеспечить доступ к полю
» Bar::i, вариантов может быть несколько

17 {
18 //На самом деле дальше код должен быть более сложный
19 delete[] i; //в общем, то надо ещё поработать с динамической памятью,
» убрать, то, что там было создано конструктором Foo(int), а то будет утечка
» памяти

20 return Foo();//сделаем так для простоты
21 }
22
23
24
25 private://Возможно надо заменить private на protected, чтоб дочерний класс мог
» обращаться к полю Foo::i

26 int* i;
27 };
28
29 class Bar: public Foo //добавил public
30 {
31 public:
32 Bar(int j)
33 {
34 i=new char[j];
35 }
36 ~Bar()
37 {
38 delete[] i; //Изменил, добавив []
39 }
40
41 private:
42 char* i;
43 };
44
45
46 int main()
47 {
48 Foo* f=new Foo(100);
49 Foo* b= new Bar(200); //Нужно в классе определить присваивание и чтоб было
» открытое наследование

50 *f=*b; //Нужно в классе определить присваивание
51 delete f;
52 delete b;
53 }



Ах, да, похоже, что надо ещё создать конструктор копирования Foo(const Foo&), надо повозится с глубоким копированием, сделать проверки в операторе присваивания, чета стало лень копать дальше.

пятница, 8 октября 2010 г.

Исчезли папки и файлы на съемном диске (flash)

Иногда подходят ко мне с проблемой, мол исчезли файлы и папки на диске. Делаю так:
Пуск - Выполнить..., набираю cmd, предположим, что съемный диск имеет имя H:\, забиваем в консоли следующее:

cd /D H:\
attrib -S -H -R *


Подробности об attrib, делаем так:

attrib /?


Интересно, что чем более удобной и технологически продвинутой становится Windows, тем больше возможностей для появления в системе вирусов. Например, файл autorun.ini в корне диска, созданный для автоматического открытия диска (запуска программ), позволяет распространять "заразу" от одного компьютера другому, путем простого подключения съемного диска.

четверг, 7 октября 2010 г.

Мета-тег от Яндекса

Добавил мета-тег от Яндекса, надеюсь, что в скором времени будет больше посещений блога, в тем более, что по некоторым оценкам, Яндекс используют как поисковую систему примерно 45% пользователей Рунета.
Добавил вот этот код проверки:

1 <meta name='yandex-verification' content='40d5e3ee817d41b6' />


Идентификатор содержит 16 символов, каждый шифрует 4 бита, 16*4=64 бита или 8 байт.
Не расточительство ли это?
Обещали проверять его наличие.