Jump to content

    
Ой ли? Сдаётся мне, что ключ -j появился далеко не сразу. И к этому времени было уже очень много таких вот "безграмотных" мейкфайлов.

Это не причина НЕ исправлять такие makefile.

Раньше и в компиляторах не было volatile. Но это не причина НЕ исправлять старый код.

Share this post


Link to post
Share on other sites
all: message_begin elf size message_end

Получается, что все эти варианты тоже будут глючить от многопоточности. Имхо, надо было и в такой перечень целей вставить «точки следования».

size сам зависит от elf, так что там без проблем, message_begin иногда выскакивает после compiling от первого %.o. Это немного неприятно, не не смертельно. Там и предупреждения/ошибки компилятора идут вперемешку с compiling по мере появления, всё равно смотреть потом внимательно надо :-)

И править это руки не доходят. А важные вещи, в отличие от декора, вроде как нормально (ну кроме make clean all).

 

По правке — полностью согласен в мнением по volatile :-)

Более того, volatile уже давно как был, но с ростом пронырливости компилятора приходится править то, где эти volatile есть, но в других местах (например, так было с чтением системного тика в scmRTOS).

Share this post


Link to post
Share on other sites
Это не причина НЕ исправлять такие makefile.

Раньше и в компиляторах не было volatile. Но это не причина НЕ исправлять старый код.

Хорошо хоть, что с этих мейкфайлов снято обвинение в «безграмотности», теперь они просто «старый код» :)

А теперь представьте, что в следующей версии make введут новый ключик, и вам придётся править все свои мейкфайлы. Имхо, это неправильно. И сравнение с volatile здесь не совсем уместно - в случае make ничто не мешало авторам поставить между субцелями пресловутые «точки следования».

Share this post


Link to post
Share on other sites
А теперь представьте, что в следующей версии make введут новый ключик, и вам придётся править все свои мейкфайлы. Имхо, это неправильно.
Неправильно будет, если ключик по умолчанию будет включен.

А так: не хош -- не пользуй, хош -- подстройся. Всё честно.

 

случае make ничто не мешало авторам поставить между субцелями пресловутые «точки следования».
«Ага, щас»™

В результате для

%.elf : $(OBJS)

между файлкми из $(OBJS) будет по точке следования и -j N идёт лесом. Параллельно их создавать будет нельзя.

Спасибо, не надо.

Я лучше пешком постою ручками всё поправлю там, где я не рассчитал на -j

Share this post


Link to post
Share on other sites
Хорошо хоть, что с этих мейкфайлов снято обвинение в «безграмотности», теперь они просто «старый код» :)

А теперь представьте, что в следующей версии make введут новый ключик, и вам придётся править все свои мейкфайлы. Имхо, это неправильно. И сравнение с volatile здесь не совсем уместно - в случае make ничто не мешало авторам поставить между субцелями пресловутые «точки следования».

ИМХО вывод сообщений неправильно организовывать как подцели какой-либо цели.

По замыслу make, подцели необязательно вообще будут выполняться by design.

Про определённый порядок выполнения зависимостей нигде никогда ничего не гарантировалось.

Всё что вы просили выполнить в вашем makefile для цели all будет добросовестно выполнено. Вывод на экран сообщений был? Размер выводился? elf собирался? При любом ключе -j ?

Проводя аналогии с компиляторами: сейчас уже никого не удивляет, что в ассемблерном листинге оптимизирующего компилятора фактический порядок "промежуточных" арифметических вычислений может отличатся от написанного в исходном тексте программы. Не говоря уже о выкидывании незадействованного кода. Если программист заложился на какие-то побочные свойства инструмента - это только ответственность программиста а не проблема инструмента.

Share this post


Link to post
Share on other sites
Про определённый порядок выполнения зависимостей нигде никогда ничего не гарантировалось.

Пока не появился ключик -j - вполне себе гарантировалось:)

Всё что вы просили выполнить в вашем makefile для цели all будет добросовестно выполнено. Вывод на экран сообщений был? Размер выводился? elf собирался? При любом ключе -j ?

Нет. В моём примере (build: clean all) - как раз-таки ничего не собиралось. Ибо сначала выполнялась цель all, а потом - clean. В результате после выполнения make build - никакого elf-а не было.

«Ага, щас»™

В результате для

%.elf : $(OBJS)

между файлкми из $(OBJS) будет по точке следования и -j N идёт лесом. Параллельно их создавать будет нельзя.

Так я про PHONY цели. Между ними (после них) вполне можно было поставить точки следования.

Share this post


Link to post
Share on other sites
У меня была именно такая цель:

build: clean all

Это не одно и то же.

Вы указали две разные цели (clean и all). Каждая из этих целей имеет свой рецепт, и при указании -j эти два рецепта выполняются параллельно.

В примере же ReAl один рецепт из двух строк. Эти строки всегда будут выполняться последовательно независимо от наличия или отсутствия -j.

Share this post


Link to post
Share on other sites
Пока не появился ключик -j - вполне себе гарантировалось:)

После этого утверждения была бы уместна ссылка на документацию какой-то определённой версии make. С подтверждением этого смелого утверждения.

Нет. В моём примере (build: clean all) - как раз-таки ничего не собиралось. Ибо сначала выполнялась цель all, а потом - clean. В результате после выполнения make build - никакого elf-а не было.

...

В этом примере для цели build необходимо удовлетворение двух взаимоисключающих подцелей. Вы так построили сценарий для make. При чём тут инструмент?

Мне вся эта ситуация напоминает появление процессоров с "Hyper-threading". Тогда программисты не были готовы к настоящему параллельному выполнению потоков и отсутствие всяких "spin_lock" приводило к непредсказуемым результатам.

Share this post


Link to post
Share on other sites
После этого утверждения была бы уместна ссылка на документацию какой-то определённой версии make. С подтверждением этого смелого утверждения.

Это совершенно очевидно. Один поток - цели выполняются последовательно.

В этом примере для цели build необходимо удовлетворение двух взаимоисключающих подцелей. Вы так построили сценарий для make. При чём тут инструмент?

Не взаимоисключающих, а последовательных. Без -j всё работает как задумано. Если бы при добавлении ключика -j ввели точки следования после каждой из PHONY-целей, то всё бы работало и с -j. Я считаю это большой глупостью авторов make.

Короче, вы меня не переубедите. Инструмент этот (make) - кривой. Уж сколько времени я им пользуюсь, а ощущение кривизны не проходит, а только усиливается.

Share this post


Link to post
Share on other sites
Это совершенно очевидно. Один поток - цели выполняются последовательно.

Очевидно? А почему не в обратном порядке? А почему не в алфавитном порядке? А почему не в порядке расположения файлов в файловой системе?

Не взаимоисключающих, а последовательных.

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

....

Короче, вы меня не переубедите. Инструмент этот (make) - кривой. Уж сколько времени я им пользуюсь, а ощущение кривизны не проходит, а только усиливается.

Жаль.

 

Тут сделал пару тестов:

all: first second third

first:
    sleep 3
    echo first

second:
    sleep 2
    echo second

third:
    sleep 1
    echo third

.PHONY: first second third

 

$ make

 

sleep 3
echo first
first
sleep 2
echo second
second
sleep 1
echo third
third

 

make -j 3

 

sleep 3
sleep 2
sleep 1
echo third
third
echo second
second
echo first
first

 

Если нам важен порядок немного патчим кривой makefile без создания промежуточных целей:

all: first second third

first:
    sleep 3
    echo first

second: | first
    sleep 2
    echo second

third: | second
    sleep 1
    echo third

.PHONY: first second third

 

make -j 3

 

sleep 3
echo first
first
sleep 2
echo second
second
sleep 1
echo third
third

 

Вуаля!

Может кому-нибудь будет полезно.

Share this post


Link to post
Share on other sites
Это совершенно очевидно. Один поток - цели выполняются последовательно.
Вы говорите о разном. :)

Совершенно бесспорно, что без -j выполнение происходит последовательно. Petka же говорил(а) о порядке обработки целей в этой последовательности. То, что рецепты выполняются последовательно, а не параллельно, под сомнение не ставилось...

 

Не взаимоисключающих, а последовательных. Без -j всё работает как задумано. Если бы при добавлении ключика -j ввели точки следования после каждой из PHONY-целей, то всё бы работало и с -j.

:) Если после каждой цели (каждого рецепта) ввести точку последовательности, то и сборка будет выполняться строго последовательно. Таким образом, весь эффект опции -j (которая как раз предписывает выполнять рецепты параллельно) будет уничтожен. В таком случае, просто не указывайте -j, и Вы получите желаемое!

 

Возможно, я просто не понял, что Вы имели в виду, говоря о точках последовательности (я понимаю "точка последовательности" как то, что новый рецепт начинает выполняться только после завершения выполнения предыдущего), в таком случае, буду благодарен за разъяснение (еще лучше с примером).

Share this post


Link to post
Share on other sites
Вы говорите о разном. :)

Совершенно бесспорно, что без -j выполнение происходит последовательно. Petka же говорил(а) о порядке обработки целей в этой последовательности.

Ну мы вроде как друг-друга поняли:) По факту порядок обработки целей совпадает с порядком их объявления. Хотя я и не встречал в документации явных гарантий этого.

:) Если после каждой цели (каждого рецепта) ввести точку последовательности, то и сборка будет выполняться строго последовательно. Таким образом, весь эффект опции -j (которая как раз предписывает выполнять рецепты параллельно) будет уничтожен.
Я написал не "каждой цели", а "каждой PHONY-цели". Так что эффект останется.

В таком случае, просто не указывайте -j, и Вы получите желаемое!

Так и делаю, не переписывать же многие десятки makefile-ов.

(И, вдохновлённый этим обсуждением, снова почитываю про scons... :) )

Share this post


Link to post
Share on other sites
Пока не появился ключик -j - вполне себе гарантировалось:)

Ключик -j очень старый, лет 10 назад он уже был старым.

 

PS. 1989г, make, ключ -j уже имеется.

Edited by e-serg

Share this post


Link to post
Share on other sites
И? Это вы к чему?

к этой фразе

Ой ли? Сдаётся мне, что ключ -j появился далеко не сразу. ...

более 20 лет, этот ключик "-j", у gnu make существует, новым его не назвать.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this