2012-06-07 4 views
1

Я пытаюсь построить отладочную и выпускную версию библиотеки с помощью Makefile и скопировать эти библиотеки в соответствующие каталоги сборки, например.Сделать несколько целей в 'all'

.PHONY: all clean distclean 

all: $(program_NAME_DEBUG) 
    $(CP) $(program_NAME_DEBUG) $(BUILD_DIR)/debug/$(program_NAME_DEBUG) 
    $(RM) $(program_NAME_DEBUG) 
    $(RM) $(program_OBJS) 
    $(program_NAME_RELEASE) 
    $(CP) $(program_NAME_RELEASE) $(BUILD_DIR)/release/$(program_NAME_RELEASE) 
    $(RM) $(program_NAME_RELEASE) 
    $(RM) $(program_OBJS) 

$(program_NAME_DEBUG): $(program_OBJS) 
    $(LINK_DEBUG.c) -shared -Wl,-soname,$(program_NAME_DEBUG) $(program_OBJS) -o $(program_NAME_DEBUG) 

$(program_NAME_RELEASE): $(program_OBJS) 
    $(LINK_RELEASE.c) -shared -Wl,-soname,$(program_NAME_RELEASE) $(program_OBJS) -o $(program_NAME_RELEASE) 

1-ая цель во всем (program_NAME_DEBUG) компилирует ОК, но второй (program_NAME_RELEASE) производит следующее сообщение об ошибке:

libGlam_rel.so 
make: libGlam_rel.so: Command not found 
make: *** [all] Error 127 

libGlam_rel.so является значением program_NAME_RELEASE

Это не похоже, признают 2-ю цель, так как она 1-го?

EDIT

наконец получил эту работу.

В одной проблеме были файлы src в нескольких каталогах, используется VPATH для сортировки, например.

# specify dirs other then current dir to search for src files 
VPATH = ../../pulse_IO/src ../../../g2/src 

В дополнение к дополнительным библиотечным целям в условное оборудование платформы, например.

# Platform specific conditional compilation 
UNAME := $(shell uname) 

TARGET := Glam 

ifeq ($(UNAME), Linux) 
# LINUX version 
program_NAME := lib$(TARGET).so 
program_DEBUG_NAME := lib$(TARGET)_dbg.so 
program_RELEASE_NAME := lib$(TARGET)_rel.so 
BUILD_DIR = ../build/linux 
endif 

ifeq ($(UNAME), MINGW32_NT-6.1) 
# WINDOWS version 
program_NAME := lib$(TARGET).dll 
program_DEBUG_NAME := lib$(TARGET)_dbg.dll 
program_RELEASE_NAME := lib$(TARGET)_rel.dll 
BUILD_DIR = ../build/windows 
endif 

добавлен новый отладки и выпуска объектных файлов:

DEBUG_OBJS := $(addprefix $(BUILD_DIR)/debug/,${program_OBJS}) 
RELEASE_OBJS := $(addprefix $(BUILD_DIR)/release/,${program_OBJS}) 

установить мой отладки и выпуска CFLAGS:

DEBUG_CFLAGS := -fPIC -g -Wall -DDEBUG=1 
RELEASE_CFLAGS := -fPIC -O2 -Wall -DDEBUG=0 

сопоставил всю отлаживать и высвобождают опции компилятора:

DEBUG_LINK.c := $(CC) $(DEBUG_CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) 
RELEASE_LINK.c := $(CC) $(RELEASE_CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) 

ad вычитал мои новые правила цели «все»:

.PHONY: all clean 

all: $(program_DEBUG_NAME) $(program_RELEASE_NAME) 

набор правил выглядит следующим образом (вкл. замена для создания неявного объектного файла):

$(program_DEBUG_NAME): $(DEBUG_OBJS) 
    $(DEBUG_LINK.c) -shared -Wl,-soname,[email protected] $^ -o $(BUILD_DIR)/debug/[email protected] 

$(program_RELEASE_NAME): $(RELEASE_OBJS) 
    $(RELEASE_LINK.c) -shared -Wl,-soname,[email protected] $^ -o $(BUILD_DIR)/release/[email protected] 

# rule to build object files (replaces implicit rule) 
$(BUILD_DIR)/debug/%.o: %.c 
    $(DEBUG_LINK.c) $< -c -o [email protected] 

$(BUILD_DIR)/release/%.o: %.c 
    $(RELEASE_LINK.c) $< -c -o [email protected] 

и прикончить я изменил чистый, чтобы справиться со всеми новыми файлами:

clean: 
    @- $(RM) $(BUILD_DIR)/debug/$(program_DEBUG_NAME) 
    @- $(RM) $(DEBUG_OBJS) 
    @- $(RM) $(BUILD_DIR)/release/$(program_RELEASE_NAME) 
    @- $(RM) $(RELEASE_OBJS) 

Это работает позволяет мне производить отладку и выпустить версии моя библиотека на платформах linux и windows с одним Makefile, например $ make -k

+0

почему? Я думаю, что я правильно использую vpath здесь, то есть ищет источники * не * цели? – bph

+0

его штраф за простой make-файл, и если это все, что вы собираетесь делать, то это нормально. вы столкнетесь с проблемами, если ваш проект начнет иметь файлы с одинаковыми именами, хотя разные пути – ThePosey

+0

ah yes - я вижу, что это будет потенциальная проблема. – bph

ответ

2

Прежде всего. Кажется, вам нужны разные версии объектных файлов для двух библиотек, но в этом make-файле ничего нет.

Существует несколько способов сделать это.Чистейший, вероятно, иметь две директории:

debug_objs/ 
    ang.o 
    naur.o 
    gul.o 

release_objs/ 
    ang.o 
    naur.o 
    gul.o 

второй-чистейшее, чтобы иметь разные имена файлов:

ang_debug.o 
    naur_debug.o 
    gul_debug.o 

    ang_rel.o 
    naur_rel.o 
    gul_rel.o 

В любом случае, вы можете написать правила для RELEASE_OBJS и DEBUG_OBJS (мы можем помочь с это, если потребуется).

Теперь рассмотрим правила библиотеки:

$(program_NAME_DEBUG): $(DEBUG_OBJS) 
    $(LINK_DEBUG.c) -shared -Wl,-soname,$(program_NAME_DEBUG) $(DEBUG_OBJS) -o $(program_NAME_DEBUG) 

$(program_NAME_RELEASE): $(RELEASE_OBJS) 
    $(LINK_RELEASE.c) -shared -Wl,-soname,$(program_NAME_RELEASE) $(RELEASE_OBJS) -o $(program_NAME_RELEASE) 

Мы можем использовать Automatic Variables, чтобы сделать их более кратким:

$(program_NAME_DEBUG): $(DEBUG_OBJS) 
    $(LINK_DEBUG.c) -shared -Wl,-soname,[email protected] $^ -o [email protected] 

$(program_NAME_RELEASE): $(RELEASE_OBJS) 
    $(LINK_RELEASE.c) -shared -Wl,-soname,[email protected] $^ -o [email protected] 

(Мы могли бы пойти немного дальше, но давайте не будем толкать его.)

Сейчас для all. Двигаемся $(program_NAME_RELEASE) в список пререквизитов, где она принадлежит:

all: $(program_NAME_DEBUG) $(program_NAME_RELEASE) 
    $(CP) $(program_NAME_DEBUG) $(BUILD_DIR)/debug/$(program_NAME_DEBUG) 
    $(RM) $(program_NAME_DEBUG) 
    $(RM) $(DEBUG_OBJS) 
    $(CP) $(program_NAME_RELEASE) $(BUILD_DIR)/release/$(program_NAME_RELEASE) 
    $(RM) $(program_NAME_RELEASE) 
    $(RM) $(RELEASE_OBJS) 

Но нет никаких причин, чтобы удалить объектные файлы, так как они не могут столкнуться, и сделать так или иначе они будут удалены, если они промежуточные файлы. И нет необходимости в $(CP), а затем $(RM), когда мы можем только mv. И нет необходимости в mv; если это где библиотеки принадлежат, мы можем построить их там в первую очередь:

all: $(program_NAME_DEBUG) $(program_NAME_RELEASE) 

$(program_NAME_DEBUG): $(DEBUG_OBJS) 
    $(LINK_DEBUG.c) -shared -Wl,-soname,[email protected] $^ -o $(BUILD_DIR)/debug/[email protected] 

$(program_NAME_RELEASE): $(RELEASE_OBJS) 
    $(LINK_RELEASE.c) -shared -Wl,-soname,[email protected] $^ -o $(BUILD_DIR)/release/[email protected] 

EDIT:
Для создания объектных файлов (я предполагаю, что вы используете C):

OBJS:= ang.o naur.o gul.o 
DEBUG_OBJS := $(addprefix debug_objs/,$(OBJS)) 
RELEASE_OBJS := $(addprefix release_objs/,$(OBJS)) 

debug_objs/%.o: $(SOURCE_DIR)/%.c 
    $(CC) $(DEBUG_FLAGS) $< -o [email protected] 

release_objs/%.o: $(SOURCE_DIR)/%.c 
    $(CC) $(RELEASE_FLAGS) $< -o [email protected] 

(Просто убедитесь, что эти каталоги exist-- вы можете автоматизировать это тоже, но вы делаете достаточно изменений, в течение одного дня.)

+0

, это выглядит великолепно - я думаю, что часть моей путаницы в том, что объектные файлы создаются автоматически, и это не то, что я хочу здесь, как вы говорите , я хотел бы иметь две цели, которые строят эти объектные файлы в два каталога, отладочную версию и версию dir - как вы это делаете? – bph

+0

Я могу оставить улучшения лаконичности - для непосвященных это делает Makefiles непроницаемым – bph

+0

@Hiett, я подумал об улучшении правил библиотеки, но я не хочу ударять вас слишком много сразу ... – Beta

1

Это изменение должно сделать:

all: $(program_NAME_DEBUG) $(program_NAME_RELEASE) 

В противном случае make all не в состоянии сделать $(program_NAME_RELEASE), который является то, что сообщение об ошибке говорит вам.

+0

спасибо, попробуем это, но удаление файлов объектов произойдет в правильном порядке , например между созданием версий отладки и выпуска библиотеки? – bph

+0

это работает так же, как и обе библиотеки, но потому, что в каждом случае используются одни и те же объектные файлы (т. Е. Они не удаляются между строками). Я фактически создаю одну и ту же библиотеку дважды, которая isn; t what i ' м пытается сделать – bph

+0

я вижу. Makefiles может быть сложным, так что давайте подумаем об этом. Очевидно, что '' (program_NAME_DEBUG): 'target не строит' libGlamdring_rel.so'. Вы хотите, чтобы это было так? – thb

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