2014-11-08 3 views
0

Мне сложно понять, как создать две жесткие ссылки на мою целевую программу. Моя целевая программа foo, и я хочу создать два hardlinks для foo, один из которых называется baz, а другой - bar. В настоящее время мой Makefile выглядит следующим образом:Жесткая ссылка в файле makefile

CC = gcc 
CFLAGS = -g -std=c99 -pedantic -Wall 
HOME = /my/home/dir 
SOURCES = main.c bar.c baz.c datastructure.c ${HOME}/addNodes.c 
OBJECTS = $(SOURCES:.c=.o) 
TARGET = foo 
LN_F = ln -f 

$(TARGET): $(OBJECTS) 
    ${CC} ${CFLAGS} -o [email protected] $^ 

%.o : %.c 
    $(CC) $(CFLAGS) -c $< -o [email protected] 

bar: ${TARGET} 
    ${LN_F} ${TARGET} bar 

baz: ${TARGET} 
    ${LN_F} ${TARGET} baz 

Проблема заключается в том, что я теперь должен создавать жесткие ссылки на Foo вручную, введя "ln -s foo bar" и "ln -s foo baz"

+2

minor point: ln -s - это символическая ссылка, а не жесткая ссылка. Вы, вероятно, не хотите жестких ссылок. Вы пытались просто добавить строку 'ln -s $ (TARGET)' после строки '$ {CC}' ...? –

+0

@GregBowser О, хорошо, я не понимал - это была символическая ссылка. Но я определенно хочу жесткую ссылку, потому что я хочу, чтобы bar и baz представляли ту же программу, что и foo, но просто имели разные имена. – Apollo

+1

Символическая ссылка сделает это. например, в моей системе: '/ bin/sh' является символической ссылкой на'/bin/bash', что в основном является тем, что вы хотите сделать. Символические ссылки - это путь в 99% случаев. Во всяком случае, просто добавление строки 'ln -s ...' в '' (TARGET) 'target должно сделать трюк. –

ответ

3

Если вы идете с символическими ссылками:

TARGET = foo 
AUX1 = bar 
AUX2 = baz 
LN_S = ln -s -f 

all: ${TARGET} ${AUX1} ${AUX2} 

${TARGET}: $(OBJECTS)               
    ${CC} ${CFLAGS} -o [email protected] $^              

${AUX1}: ${TARGET} 
    ${LN_S} ${TARGET} ${AUX1} 

${AUX2}: ${TARGET} 
    ${LN_S} ${TARGET} ${AUX2} 

Если вы идете с жесткими ссылками, вы будете использовать ln -f (без -s). Обратите внимание, что однажды (очень) давным-давно -f не поддерживался ln (и в те дни -s также не был вариантом - я говорю об этом давно) и такое правило, как эти правила привязки будет использовать rm -f, чтобы удалить ссылку перед запуском команды ln.

Вы также можете написать ссылку строку, используя общие макросы [email protected] и $? (это надежные, POSIX поддерживаемых макросов):

${AUX2}: ${TARGET} 
    ${LN_S} $? [email protected] 

Это работает здраво, потому что есть только одна предпосылки для ${AUX2}; если было несколько предварительных условий, $? не сработает - будьте осторожны.

+0

Это неверно.В ваших правилах для символических ссылок есть две тонкие ошибки: во-первых, зависимость от цели должна быть только порядка, второй флаг 'ln -f' должен использоваться для правильной поддержки опции Make--B. –

+0

Цели $ {AUX1 | 2} должны фактически выполнять «rm $ @», прежде чем пытаться создать символическую ссылку, также предположим, что линия ссылок: $ {LN_S} -f $^$ @ – user3629249

+0

@ user3629249 почему они должны Удалить? Если у вас есть веская причина, скажите мне, чтобы я мог учиться. В общем, в make-файлах лучше избегать «rm», а затем делать их снова, потому что это изменяет каталог, и могут быть цели, зависящие от каталога. Всегда должно быть лучше попытаться просто заменить файл на место, не мгновенно удаляя его. –

0

Ничто в ваших сообщениях и комментариях не объясняет, зачем нужны жесткие ссылки. Поэтому я продолжу линию своего предшественника, пытаясь показать вам, как это сделать с помощью бесплатных ссылок.

Правильный способ создания символической ссылки на цель в Makefile, как это:

TARGET := foo 
LINK := bar 

$(LINK): Makefile | $(TARGET) 
    ln -sf $| [email protected] 

Эта зависимость должна быть порядка только потому, что вы не зависят от изменений к цели, вы только все равно, что он существует, поэтому у вас нет висячей ссылки, что плохо.

-f опция необходима для поддержки GNU Сделать -B вариант.

Смежные вопросы