В поисках альтернатив C++

В связи со своим вынужденным переходом в разработчики Java я получил довольно интересную возможность посмотреть на C и C++ со стороны. В целом, мне нравится то что я вижу глядя на C++ с позиции Java разработчика, но, само собой, нашлось одно «но», которое, если быть честным, мне и раньше не давало покоя: C++ совершенно не подходит для быстрого прототипирования. По большому счету это единственный недостаток который я отмечаю на данный момент.

Если говорить про Java, то с быстрым прототипированием тут все нормально, в то время как скорость разработки приложений приблизительно такая же•• как и в случае с C++, ну может на 10% быстрее. При этом язык крайне ограниченный, практически до убогости, что после 10 лет разработки на C++ вызывает довольно ощутимое отторжение.

Понимая, что так дело не пойдет, я взялся за поиск приличной альтернативы C++. Изначально подумывал про Erlang, ведь в основном я пишу что-то сетевое, но в итоге от этого варианта решил отказаться, потому как за пределами сетей Erlang мягко говоря бесполезен, а в самих сетях, зачастую, ограничен в плане набора доступных библиотек. В результате довольно долгих поисков выбор остановился на JVM, ведь JVM — это действительно кроссплатформенное решение (в отличие от того же CLR) с большой базой библиотек под нормальными лицензиями (MIT, BSD и, в худшем случае, LGPL). Плюс, в JDK, начиная с 7-й версии, появилась поддержка асинхронного ввода/вывода, т.е. возникла вполне реальная возможность писать не тормозящие где попало сетевые приложения.

К основным языкам базирующимся на JVM, само собой за исключением самой Java, относятся Clojure, Groovy и Scala. Clojure — Lisp-подобный язык, так что отмел его сразу. Да, я к Lisp отношусь хорошо, но вот куча народу вокруг — нет, так что никакой возможности реально использовать что-то Lisp-подобное я не вижу. Groovy — хороший язык, но без чего-то действительно цепляющего. А вот Scala… Да, Scala — это язык с довольно крутой кривой вхождения, при этом богатым синтаксисом и отличными возможностями.

У всех разные способы оценить пригодность языка для своих нужд. Кто-то первым делом реализует быструю сортировку, кто-то пишет Hello World. А я, обычно, пишу Echo-сервер с клиентом. Continue reading

Vim + Cscope

Уже не помню, как я перешел с ctags на cscope, но он реально крайне удобен и всеяден. Небольшой скриптик для автоматического построения/обновления тагов начиная с текущей директории. Работает на редкость шустро.

function! UpdateCscopeDb()
    let extensions = [""*.cpp"", ""*.h"", ""*.hpp"", ""*.inl"", ""*.c"", ""*.java""]
    let update_file_list = "find . -name " . join(extensions, " -o -name ") . " > ./cscope.files"
    echo update_file_list
    echo system(update_file_list)
    echo system("cscope -b")
    cscope kill 0
    cscope add .
endfunction

nmap <F12> :call UpdateCscopeDb()<cr>
vmap <F12> <esc>:call UpdateCscopeDb()<cr>
imap <F12> <esc>:call UpdateCscopeDb()<cr>

Синхронизация рабочих настроек

На всех своих рабочих/домашних UNIX* машинах я использую одни и те же конфигурационные файлы для VIM-a, Gdb, Zsh и прочего. После того как в один из них вносится изменение, хочется “легко и изящно” получить его на всех остальных машинах. С учетом того, что облачные хранилища получили очень широкое распространение, это сделать проще простого. Пишем небольшой bash скрипт и добавляем его в cron:

#!/bin/sh
# set -x-
FLAGS=-lzuogthvr
SYNC_LIST=".vim .vimrc .gdbinit .gdb_stl .zshrc confsync.sh"
SOURCE_DIR=~
EXCLUDE_LIST=""
EXCLUDE_COMMAND=""

if [ -z "$BACK_UP_DIR" ]; then
    BACK_UP_DIR=~/Dropbox/backup/
fi

if [ ! -d "$BACK_UP_DIR" ]; then
    mkdir "$BACK_UP_DIR"
else
    rsync $FLAGS --update --progress $BACK_UP_DIR/ $SOURCE_DIR
fi

for s in $EXCLUDE_LIST; do
    EXCLUDE_COMMAND="$EXCLUDE_COMMAND --exclude "$s""
done

for d in $SYNC_LIST; do
    rsync $FLAGS --update --progress $d $BACK_UP_DIR $EXCLUDE_COMMAND
done

Java + Ant + сетевой диск

Java – наверное самая уродская платформа из всех, с какими я имел дело. Ну и Ant не дальше ушел.
Итак, дано: Linux, сетевой диск с парой гагабай исходников, ant, java, gcc. Простейшая команда ant clean приводит к исключению java.lang.OutOfMemoryError. Перепробовал все найденные в интернете способы изменения объема используемой памяти и прочих шаманских действий – не помогает.
Стал эксперементировать дальше, выяснил, что падает только на сетевых шарах(!!!). Скопировал локально – полет нормальный. Спрашиватся, ну какого хера ошибка OutOfMemoryError, а не что-то подходящее в данной ситуации?!
Вобщем, осталось только процесс копирования автоматизировать.

Альтернативы

Открыл для себя древнюю, но крайне полезную утилитку update-alternatives. Эта утилитка просто незаменима если приходится работать c кривыми не совсем удачными сборочными файлами.
Небольшой пример. У нас есть куча проектов, которые необходимо собирать разными JDK. Что-то собирается при помощи 1.5, что-то 1.6 и вообще ничего нельзя собрать OpenJDK. При переключении с проекта на проект надо либо каждый раз пересоздавать линки на нужный компилятор, либо можно воспользоваться update-alternatives. Continue reading

fstab

Это прям какая-то магия, но каждый раз когда я сталкиваюсь с fstab, у меня уходит куча времени на то чтобы в него что-то прописать. На этот раз мне понадобилось добавить Windows-шары на машину с Fedora 15. И теперь я решил все записать, чтоб уж в следующий раз точно не забыть как же это делается. Continue reading

Внешние проекты в CMake

Я просто весь мозг сломал со следующей ситуцией. Есть CMake проект состоящий из нескольких библиотек и исполнимого модуля. Этот проект использует некую внешнюю по отношению к нему библиотеку. В идеале, в процессе сборки, эту библиотеку надо скачать, собрать, установить и заюзать.
Перечирав кучу документации и устав от эксперементов, я наткнулся на чудесную функцию externalproject_add.

externalproject_add(
    memtree_external
    GIT_REPOSITORY "git@github.com:astavonin/memtree.git"
    CMAKE_ARGS
        -DCMAKE_INSTALL_PREFIX:STRING=${PROJECT_BINARY_DIR}
    UPDATE_COMMAND ""
)
add_library(memtree SHARED IMPORTED)
set_property(TARGET memtree PROPERTY
    IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libmemtree.a)
include_directories(${PROJECT_BINARY_DIR}/include)

Для того чтобы установка отрабатывала корректно, пришлось добавить несколько строк в CMakeLists.txt

install(FILES ../include/memtree/memtree.h DESTINATION include/memtree)
install(TARGETS memtree DESTINATION lib EXPORT memtree-targets)
install(EXPORT memtree-targets DESTINATION lib/memtree)

Уфф. Убил на это кучу времени, но оно того стоит – обновлять библиотеку теперь куда проще