Подтвердить что ты не робот

Настройка emacs для cmake

gcc 4.4.2 cmake 2.6

Я только начал использовать cmake. Исходя из написания собственных Makefile.

Однако у меня есть эта структура каталогов и использование сборки вне источника. Отделить исходные файлы от файлов сборки.

project
    src
        my_c_files.c
        CMakeLists.txt
    build
        Makefile

Прежде чем писать собственные файлы Makefile в каталоге src, а затем нажмите F5, я смог скомпилировать свою программу. И emacs перечислит любые предупреждения или ошибки. Однако мне кажется, что я должен открыть терминал и перейти в каталог сборки, чтобы запустить

cmake ../src

а затем

make

Я хотел бы запустить make изнутри emacs так же, как нажать F5. Но поскольку Makefile был создан в каталоге сборки, а emacs ищет его в каталоге src.

Даже когда я установил мягкую ссылку на Makefile в каталоге src для ссылки на Makefile в каталоге сборки. Все это дало мне список ошибок.

4b9b3361

Ответ 1

Для точно такой же цели я нашел .dir-locals.el чрезвычайно полезным, вот как выглядит один из моих:

((nil . ((tab-width . 8)
     (indent-tabs-mode . t)))
 (c++-mode . ((c-basic-offset . 8)
          (tab-width . 8)
          (indent-tabs-mode . t)
          (compile-command . "make -C ../build -j 2 run_tests")))
 ((c-mode . ((c-basic-offset . 8)
         (tab-width . 8)
         (indent-tabs-mode . t)
         (compile-command . "make -C ../build -j 2 run_tests")))))

Очевидно, что у меня могут быть пути, указанные в разных .dir_locals.el в соответствии с их местоположением, и, например, некоторые build run_tests для unit test, некоторые из них строят реальную цель и т.д.

Затем я помещаю в каталог сборки фиктивный makefile, который выглядит следующим образом:

all: run_tests

run_tests:
    @cmake ..
    @make -j 2

Таким образом, я могу сделать чек и запустить M-x compile в любом файле, который мне нравится, и он пойдет правильно. Я использую git, и этот Makefile игнорируется при мониторинге с помощью git следующим образом:

git update-index --assume-unchanged Makefile

и если я хочу изменить и зафиксировать его, я делаю

git update-index --no-assume-unchanged Makefile.

Таким образом, новый созданный cmake Makefile не будет отображаться в git status как измененный, и я не буду его совершать случайно.

Преимущества такого подхода:

  • так как cmake использует абсолютные пути внутри, абсолютно нет проблем с перекосом ошибок компиляции в буфере компиляции, просто нажимая enter на них.

  • вы можете указать любые правила отступов, которые вы там хотите, и они могут быть разными в разных проектах или даже в каталогах, если вы так захотите:)

  • вы можете указать любое количество желаемых целей в разных проектах, даже в каталогах, по-прежнему использовать один и тот же старый M-x compile (привязанный к C-c b) и заставить Emacs поступать правильно.

Единственный недостаток, заключающийся в наличии .dir-locals.el в ваших подкаталогах, который я вряд ли нахожу плохой.

ИЗМЕНИТЬ: robUK, чтобы ответить на ваш комментарий:

Ниже приведена документация для локальных переменных для каждого каталога, как они ее называют в руководстве Emacs. Это не пакет, это часть Emacs, хотя я не уверен, был ли он доступен в версиях до 23, я использую 23.1.1.

EDIT2: liwp, чтобы ответить на ваш вопрос:

Как уже указывал Чарльз, и как говорится в документации:

Если вы поместите файл со специальным именем .dir-locals.el в каталоге, Emacs прочитает его при посещении любого файла в этом каталоге или любом из его подкаталоги, а также применить настройки он указывает на файловый буфер. Emacs ищет .dir-locals.el начиная с каталога посетил файл и дерево каталогов. (Чтобы избежать замедления, этот поиск пропускается для удаленного файлы.)

Вам не нужно .dir-locals.el всюду в вашем дереве проектов. Заметьте, однако, это, вероятно, зависит от сложности вашей базовой структуры кода.

Обычно я бы выбрал довольно простой макет:

/project_root_dir
    /build
    /src
    /test

и у меня были бы несколько разные цели, указанные в разных .dir-locals.el, скажем, в /test Я бы только построил testrunner и выполнил бы это, я потратил бы большую часть времени разработки на создание этой цели. Тогда в /src я бы сначала построил тот же testrunner, выполнил ли он, и если все будет хорошо там, это создаст мне мою главную цель проекта. Если вам это не нужно, вы можете быть в порядке только с одним .dir-locals.el под /project_root_dir. Если ваша исходная структура и требования намного сложнее, это может означать, что вам понадобится немного больше волшебства, связанного с путями и целями.

Ответ 2

Более общим решением для команды компиляции будет:

cd ${PWD%/src/*}/build && cmake ../src && make

Переменная среды PWD содержит каталог, в который вы редактируете файл; расширяя его с помощью %/src/*, вы вернетесь к корню проекта, не беспокоясь о том, сколько ../ вам нужно.

Ответ 3

Я использую EDE из Cedet для настройки проектов для работы с CMake. Посмотрите в мою конфигурацию CEDET, начиная с строки 105, например кода для конфигурации проекта. Я использую отдельные папки Debug и Release для разных сборников, и по умолчанию компиляция работает только для режима Debug....

Ответ 4

Простое решение: установите cpputils-cmake, тогда вам будет хорошо.

Объяснение: CMake уже поместил всю информацию в каталог сборки. Вам просто нужно взломать переменную ELisp compile-command в c++-mode-hook и c-mode-hook, если вы получите правильную информацию из cmake.

Две точки для идеального решения:

  • Код elisp должен определять, использует ли текущий проект CMake, сканируя исходный каталог до взлома compile-command

  • Полностью путь к каталогу на выходе из исходного источника должен быть автоматически обнаружен и добавлен в команду make -C.

Я написал плагин emacs cpputils-cmake https://github.com/redguardtoo/cpputils-cmake, который решит эти два вопроса. Проверьте мой код, и вы можете установить его, хотя менеджер пакетов Emacs.

BTW, После создания каталога создается cmake, обычно cmake не следует явно вызывать в командной строке. make -C out-of-source-build-dir достаточно умен, потому что Makefile в этом каталоге все равно вызовет cmake. Даже после изменения CMakeLists.txt вызова make -C out-of-source-build-dir все еще достаточно. Я почти уверен в этом, потому что я использую cmake в течение четырех лет.

Многие предыдущие ответы не будут работать, потому что:

  • Любое предположение о макете исходного дерева может быть неправильным. Например, я называю свой корневой исходный каталог "mysrc" вместо "src"

  • Как я использую стратегию вне источника, сложно. Например, я могу создать только один компонент, используя out-of-source.

Ответ 5

Вы можете изменить текущий рабочий каталог, который emacs использует с помощью M-x cd<enter> <path to build dir><enter>. После этого, когда вы запустите M-x compile, make будет запущен в новом рабочем каталоге. Это фактически то же самое, что запуск make на терминале в каталоге сборки, поэтому он должен работать для вас просто отлично.

Ответ 6

Как насчет использования опции -C для make?

Нажмите F5 или M-x compile, когда emacs запросит команду компиляции, введите:

make -C ../build

Ответ 7

Измените команду, чтобы использовать абсолют вместо относительного pat. EG:

cmake ~/workspace/project/src && make