Установка системных переменных сборки, зависящих от проекта

#sublimetext3 #sublime-build

#sublimetext3 #sublime-сборка

Вопрос:

Я написал систему сборки, которая вызывает скрипт bash или пакетной сборки. На данный момент я копирую и вставляю скрипт сборки в любой новый проект и изменяю связанные с проектом свойства.

Чтобы избежать необходимости каждый раз изменять сценарий (или использовать только тот, который был бы установлен глобально, например) Я хотел бы иметь возможность установить некоторые переменные в настройках проекта sublime и получить их в системе сборки, затем отправить их скрипту в качестве аргументов.

Выполнимо ли это без необходимости определять систему сборки для каждого проекта?

На случай, если это уместно, вот несколько упрощенных сценариев сборки

 #!/bin/bash
exe=some_defined_exe

mkdir -p build
cd build
cmake ..
make -j4 
make install
cd ../bin
$exe
cd ..
  

И построить систему

 {
    "cmd": ["build.sh"],
    "working_dir": "${project_path:${folder}}",
    "shell": false,
}
  

И я хотел бы, чтобы они были чем-то вроде

 #!/bin/bash
exe=$1

mkdir -p build
cd build
cmake ..
make -j4 
make install
cd ../bin
$exe
cd ..
  

и

 {
    "cmd": ["build.sh", "${some_project_defined_variable}"],
    "working_dir": "${project_path:${folder}}",
    "shell": false,
}
  

Комментарии:

1. Это невозможно, если вы не создадите модифицированную версию exec.py программы, лежащей в основе стандартных систем сборки.

Ответ №1:

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

Пользовательские системы сборки разрешают свойство с именем target , которое указывает команду для выполнения, для запуска сборки. Если вы не предоставляете это (большинство систем сборки этого не делают), по умолчанию используется exec команда. Вы могли бы создать свою собственную пользовательскую команду, которая может выполнять расширения за вас.

В качестве простого примера смотрите следующий исходный код python, который вы можете сохранить как что-то вроде custom_build.py в вашем User пакете. Это реализует новую команду с именем my_custom_build . При выполнении этой команды она преобразует свои аргументы, расширяя переменные, а затем выполняет с ними команду по умолчанию exec .

 import sublime, sublime_plugin

# List of variable names we want to support
custom_var_list = ["proj_var_1"]

class MyCustomBuildCommand(sublime_plugin.WindowCommand):
    def createExecDict(self, sourceDict):
        global custom_var_list

        # Get the project specific settings
        project_data = self.window.project_data ()
        project_settings = (project_data or {}).get ("settings", {})

        # Get the view specific settings
        view_settings = self.window.active_view ().settings ()

        # Variables to expand; start with defaults, then add ours.
        variables = self.window.extract_variables ()
        for custom_var in custom_var_list:
            variables[custom_var] = view_settings.get (custom_var,
                project_settings.get (custom_var, ""))

        # Create arguments to return by expanding variables in the
        # arguments given.
        args = sublime.expand_variables (sourceDict, variables)

        # Rename the command paramter to what exec expects.
        args["cmd"] = args.pop ("command", [])

        return args

    def run(self, **kwargs):
        self.window.run_command ("exec", self.createExecDict (kwargs))
  

В частности, сначала он ищет переменные в настройках, указанных в текущем представлении, и, если они там не найдены, в настройках, специфичных для проекта. Все переменные, которые все еще не найдены, по умолчанию имеют значение пустой строки.

Вам нужно будет указать пользовательскую систему сборки, такую как:

 {
    "target": "my_custom_build",
    "command": ["build.sh", "${proj_var_1}"],

    "working_dir": "${project_path:${folder}}",
    "shell": false
}
  

Обратите внимание, что теперь есть target поле, которое указывает, что пользовательская команда должна выполняться вместо exec . Обратите также внимание, что вместо указания командной строки как cmd , мы указываем ее как command здесь вместо этого.

Это связано с тем, что Sublime, похоже, предварительно расширяет значения известных ключей в системах сборки перед запуском вашей пользовательской команды. В результате этого он попытается развернуть переменные в cmd ключе, что приведет ${proj_var_1} к расширению до пустой строки еще до того, как наша команда ее увидит, что приведет к ее удалению.

Чтобы обойти это, мы меняем имя ключа на что-то, что Sublime оставит в покое, а затем меняем его обратно в коде.

Как написано, приведенный выше код попытается расширить любые переменные, которые он видит в любом месте системы сборки, но таким образом требуется особая осторожность для защиты cmd ключа. Вам нужно сделать что-то подобное, если вы хотите использовать свои пользовательские переменные в working_dir ключе, например.