jamplus: командная строка ссылки слишком длинная для osx

Я использую jamplus для создания кроссплатформенного проекта поставщика. В osx командная строка инструмента C (подаваемая через clang в ld) слишком длинная.

Файлы ответов — это классический ответ на слишком длинные командные строки: в руководстве jamplus указано, что их можно генерировать на лету.

пример в руководстве выглядит так:

actions response C++
{
    $(C++) @@(-filelist @($(2)))
}

Почти готово! Если специально выбить команду C.Link, вот так:

actions response C.Link
{
    "$(C.LINK)" $(LINKFLAGS) -o $(<[1]:C) -Wl,-filelist,@($(2:TC)) $(NEEDLIBS:TC) $(LINKLIBS:TC))
}

в моем файле jamfile я получаю нужную мне командную строку, которая передается компоновщику, но файл ответов не заканчивается новой строкой, поэтому ссылка не работает (osx ld требует записей, разделенных новой строкой).

  1. Есть ли способ расширить список jamplus, объединенный с новыми строками? Я безуспешно пытался использовать расширение соединения $(LIST:TCJ=\n). $(LIST:TCJ=@(\n)) тоже не работает. Если я смогу это сделать, надеюсь, сгенерированный файл будет правильным.
  2. Если нет, то какой код jamplus я могу использовать, чтобы переопределить команду link для clang и создать содержимое на лету из списка? Я ищу наименее инвазивный способ справиться с этим - в идеале, изменить/переопределить инструмент напрямую, вместо добавления новых косвенных целей везде, где требуется ссылка - поскольку это кодовая база нашего поставщика, желательно как можно меньше редактирования.

person Epu    schedule 17.01.2015    source источник
comment
Если бы кто-то, просматривающий это с репутацией более 1500, мог создать и добавить тег jamplus, это было бы здорово.   -  person Epu    schedule 17.01.2015
comment
добавлен тег jamplus   -  person Jamie    schedule 15.01.2020


Ответы (2)


Синтаксис, который вы ищете:

newLine = "
" ;

actions response C.Link
{
    "$(C.LINK)" $(LINKFLAGS) -o $(<[1]:C) -Wl,-filelist,@($(2:TCJ=$(newLine))) $(NEEDLIBS:TC) $(LINKLIBS:TC))
}

Чтобы было ясно (я не уверен, как StackOverflow отформатирует приведенное выше), переменную newLine следует определить, набрав:

newLine = "" ;

Затем поместите карат между двумя кавычками и нажмите Enter. Вы можете использовать эту же технику для некоторых других символов, т.е.

tab = "    " ;

Опять же, начните с newLine = "", а затем поместите карат между кавычками и нажмите вкладку. В приведенном выше на самом деле 4 пробела, что неправильно, но, надеюсь, вы поняли идею. Еще полезно иметь:

dollar = "$" ;

Последнее полезно, поскольку $ обычно используется для указания переменных, поэтому наличие долларовой переменной полезно, когда вы действительно хотите указать долларовый литерал. Что бы это ни стоило, Jambase, который я использую (тот, который поставляется с JamPlus, который я использую), имеет следующее:

SPACE = " " ;
TAB = " " ;
NEWLINE = "
" ;

Около строки 28...

person Steven Craft    schedule 04.04.2016
comment
Я также вижу NEWLINE в своей базе jamplus. Несмотря на то, что это было больше года назад, я взволнован, чтобы попробовать это. - person Epu; 05.04.2016
comment
Я заменил $(NEWLINE) и увидел, что содержимое файла ответов, распечатанного jamplus, теперь правильно разделено. Ты классный, Стивен! Это меня совсем убило. Обновление вашего ответа. - person Epu; 05.04.2016

  1. Я отказался от попыток использовать экранированные символы новой строки и другие специфичные для языка символы в соединениях строк. Может быть, есть отличный способ сделать это, который было слишком сложно обнаружить.

  2. Используйте многошаговую команду оболочки с несколькими временными файлами.

Для jamplus (и, возможно, других вариантов jam) раздел actions response {} между фигурными скобками становится встроенным сценарием оболочки. А синтаксис файла ответов @(<value>) возвращает имя файла, которое может быть назначено в сценарии оболочки, с содержимым, установленным на <value>.

Таким образом, код вида:

actions response C.Link
{
    _RESP1=@($(2:TCJ=#)#$(NEEDLIBS:TCJ=#)#$(LINKLIBS:TCJ=#))
    _RESP2=@()
    perl -pe "s/[#]/\n/g" < $_RESP1 > $_RESP2
    "$(C.LINK)" $(LINKFLAGS) -o $(<[1]:C) -Wl,-filelist,$_RESP2
}

создает пару временных файлов, назначенных именам переменных оболочки _RESP1 и _RESP2. Файлу по пути _RESP1 назначается содержимое расширенной последовательности, соединенной символом #. Поиск и замена выполняются с помощью perl one liner в _RESP2. И ссылка идет по плану, а jamplus очищает промежуточные файлы.

Я не мог сделать это с такими символами, как :;\n, но # работал до тех пор, пока у него не было смежных пробелов. Не совсем доволен, но идем дальше.

person Epu    schedule 22.01.2015
comment
Да, но это влияет на команду C.Link для всех проектов при использовании SubDirs и может сломать остальные. Было бы здорово узнать, как я могу применить это только к одной цели. - person Epu; 24.01.2015
comment
Ах. Добавление сюда любых пустых списков (гарантировано, что будет назначено только $2) сломает все дело. Переосмысление. - person Epu; 26.01.2015
comment
В итоге я заменил это временным встроенным сценарием / heredoc на интерпретируемом языке по своему выбору и вызвал его. Это было некрасиво, но теперь оно справляется со всеми моими крайними случаями. - person Epu; 04.02.2015