LINUX.ORG.RU

make и правила для сборки различных частей одной библиотеки в многопотоке

 , , ,


0

2

Значит дали нам в школе задание самостоятельно имплементировать ряд функций из libс. А в качестве бонуса на повышенную оценку можно написать еще и несколько функций для работы с листами.

Все это должно собираться с помощью make, используя для создания библиотеки ar, и никаких этих ваших libtool. Основная часть должна собираться правилом $(NAME), бонусная bonus. Но собираться они должны в один файл $(NAME) - скажем lib.a и оба правила не должны делать что-либо если этого не требуется.

После чего я написал не хитрые правила

.PHONY: $(NAME) bonus

$(NAME): $(NAME)($(OBJ))

bonus: $(NAME)($(OBJ_BONUS))

Естественно указав все необходимые специальные переменные (особенно флаг U - отключение детерминистического режима для ar), и все заработало как надо, до тех пор пока я не решил запустить make с флагом -j.

При запуске нескольких потоков make видимо пытается добавить одновременно несколько объектников в архив, что приводит к тому что в архиве оказываются лишь некоторые из них. В случае с правилом $(NAME), так как цель является действительно изменяемым файлом можно написать так:

$(NAME): $(OBJ)
    $(AR) $(ARFLAGS) $@ $?

Но что делать с правилом bonus я не знаю. Я думал может быть мне поможет .SECONDEXPANSION, но

.PHONY: bonus
.SECONDEXPANSION

$(NAME): OBJ ?= $(OBJ_MAIN)
bonus: OBJ ?= $(OBJ_BONUS)

$(NAME): $$(OBJ)
    $(AR) $(ARFLAGS) $@ $?

bonus: $(NAME)

Не дало ожидаемых результатов, по сему нуждаюсь в вашей помощи.



Последнее исправление: juf (всего исправлений: 2)

Сделать bonus ссылкой на архив?

archive_ref: module.o
	touch archive
	ln -fs archive archive_ref

А по поводу параллельной сборки и архивов со скобочной нотацией - вот, как-то давно штудировал доку, запомнилось.

kvpfs ★★
()
Ответ на: комментарий от kvpfs

Спасибо, это действительно хорошее решение. Правда я заменил символические ссылки на жесткие. Мне кажется что так должно быть быстрее да и проще, потому что никакая программа не сотрет случайно основной файл, но может быть я не учел каких-то подводных камней. Так можно ли здесь без опаски использовать жесткие ссылки?

$(NAME): $(OBJ)
	$(AR) $(ARFLAGS) $@ $?

all: $(NAME_ALL)

bonus: $(NAME_BONUS)

$(NAME_BONUS):: $(OBJ_BONUS) | create_bonus_link
	$(AR) $(ARFLAGS) $@ $?

create_bonus_link:
	touch $(NAME)
	ln - f $(NAME) $(NAME_BONUS)

$(NAME_ALL):: $(OBJ) $(OBJ_BONUS) | create_all_link
	$(AR) $(ARFLAGS) $@ $?

create_all_link:
	touch $(NAME)
	ln -f $(NAME) $(NAME_ALL)
juf
() автор топика
Ответ на: комментарий от juf

Гадская проверяющая система поставила мне 0, за использование ln, потому что его нет в том контейнере где запускаются тесты. Я сегодня пойду разговаривать с администрацией на эту тему, но может быть есть еще какие-то решения чисто силами make? Кроме костыля вида:

bonus:
    $(MAKE) $(NAME) OBJ=$(OBJ_BONUS)`
juf
() автор топика
Ответ на: комментарий от juf

Это не костыль. Один и тот же целевой файл (libc.a) должен собираться из разных зависимостей исходя из имени таргета. Make так не умеет. Можно решить только рекурсивным вызовом make с передачей конфигурации в переменных:

.PHONY: libc
libc:
	$(MAKE) OBJS="libc1.o libc2.o" libc.a
.PHONY: bonus
bonus:
	$(MAKE) OBJS="libc1.o libc2.o bonus1.o bonus2.o" libc.a
libc.a: $(OBJS)
	$(AR) $(ARFLAGS) $@ $^
.SUFFIXES: .c .o
.c.o:
	$(CC) $(CFLAGS) -o $@ -c $<

iliyap ★★★★★
()
Ответ на: комментарий от iliyap

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

t184256 ★★★★★
()
Ответ на: комментарий от t184256

Да, я тоже считаю, что такое задание идиотское.

iliyap ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.