Примерно раз в год я возвращаюсь к работе над некоторыми 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