Примерно раз в год я возвращаюсь к работе над некоторыми C/C++ проектами. И каждый раз я сталкиваюсь с неудобствами работы CEDET + EDE. Сначала я попробую описать свои невзгоды, а в конце предложу свой вариант сделать жизнь чуточку лучше. Комментарии приветствуются.

Какова вообще задача использовать EDE? Я хочу указать где-то все зависимости для конкретного проекта и передать эту информацию в semantic для навигации по коду и авто дополнений. И есть (по-моему здравое) желание не смешивать эту информацию для различных проектов. По-идее большего от EDE мне не надо. Ну может еще команду для сборки проекта добавить. Хотя предпочитаю делать подобное в отдельно взятой консоли. Итак, что нам предлатает Emacs Development Environment.

Пара слов про проекты по-умолчанию (то что создается с помощью ede-new). Больше всего меня бесит настройка через customize-подобный интерфейс. Им вообще не пользоваться для настройки Emacs'а в принципе. Если пойдешь сам что-то править в EDE файле, то точно натолкнешься на беду. Как минимум придется перезапускать Emacs или пересоздавать проект. Кроме того, либо я что-то потерял, либо в проекте по-умолчанию нельзя указать список include папок. Смысла в данном типе EDE-проекта на мой взгляд нет. Можно видимо использовать его для генерации make-файлов, но как показывает практика их писать и поддерживать лучше самому. Automake и подобное вам в помощь.

Также с помощью EDE можно добавить и работать с некоторыми существующими проектами. Например, есть проекты для C/C++ (ede-cpp-root-project), Java (ede-java-root-project) и другие. В них как раз можно указать внешние зависимости, и Semantic с переменным успехом их обрабатывает. Но есть одно но: почему-то эти настройки нельзя положить в Project.ede файл для полного счастья.

Видел такое решение: указать настройки всех проектов в конфигурационных файлах Emacs. Это мне тоже не нравится. Моя Emacs конфигурация все пухнет и пухнет, как я не пытаюсь ее аккуратно структурировать. Если еще там будет информация о всех проектах жизнь станет ужасна.

Была у меня идея положить все настройки в .dir-locals.el. Но тут мы сталкиваемся с проблемой множественного создания одного и того же проекта для каждого открытого файла. По-идее можно написать всю обработку этого случая внутри .dir-locals.el, но так пришлось бы тянуть и копировать это решение в каждый проект. Не айс. Хочется более универсального решения.

В общем к чему это я все. Для себя я написал небольшой хук для c-mode, который загружает конфигурацию проекта из .Project файла, если он еще не был загружен. Также он обновляет список include путей для clang, который используется в auto-complete-clang и flycheck.

(defun init/project-update ()
  (let* ((proj-file ".Project")
         (ede-proj (ede-current-project))
         (proj-dir-tmp (locate-dominating-file buffer-file-name proj-file))
         (proj-dir (when proj-dir-tmp (expand-file-name proj-dir-tmp)))
         (root-dir (when ede-proj
                     (expand-file-name
                      (ede-project-root-directory ede-proj)))))

    (when (and proj-dir (not (equal proj-dir root-dir)))
      (message "load project %s" proj-dir)
      (let ((default-directory proj-dir))
        (load (expand-file-name proj-file)))))

  (let* ((ede-proj (ede-current-project))
         (root-dir (when ede-proj
                     (ede-project-root-directory ede-proj))))
    (when root-dir
      (setq flycheck-clang-include-path
            (mapcar (lambda (item)
                      (concat root-dir item))
                    (oref ede-proj include-path)))
      (make-variable-buffer-local 'ac-clang-flags)
      (setq ac-clang-flags
            (mapcar
             (lambda (item)
               (concat "-I" item))
             flycheck-clang-include-path)))))

А сам .Project файл лежит в корне проекта и содержит только описание проекта (как видите реальной проверки на это нету). Например вот такое:

(ede-cpp-root-project "NewProject"
                      :name "NewProject"
                      :file "Makefile"
                      :include-path '("/inc")
                      :system-include-path '("/usr/include/")
                      :spp-table '(("PROJECT_EXPORT" . "")))

В душе я надеюсь, что я что-то делаю не так, что все в реальности легко и просто настраивается. Что на самом деле я просто где-то пропустил правильный вариант настройки в мануале CEDET. Если это действительно так, укажите на мою ошибку. Если же эти хуки являются единственным вариантом для удовлетворения моих запросов, то оформлю минорный мод для поддержки автоматической загрузки проектов. В общем делитесь вашими вариантами и впечатлениями от использования EDE.


P.S. Все эти негативные впечатления от использования EDE видимо возникли в результате годового использования Eclipse и Idea для программирования на Java. Пробовал Emacs заточить для Java, но затея не увенчалась успехом. Но для C/C++ проектов только Emacs, только хардкор.



Comments

comments powered by Disqus