Установка переменной ОС из правила - PullRequest
1 голос
/ 07 декабря 2011

Я пытаюсь создать общую библиотеку с одним набором кода, и все работает, кроме этой проблемы с моим Makefile. Вот мой (упрощенный) Makefile до сих пор:

OBJS = bar.o

libfoo.so:    OS = LINUX      # These don't seem to happen
libfoo.dll:   OS = WINDOWS

# Linux
ifeq ($(OS), LINUX)
CC = gcc
...

# Windows
else ifeq ($(OS), WINDOWS)
CC = i686-pc-mingw32-gcc
...
endif


all: libfoo.so libfoo.dll

libfoo.so: clean $(OBJS)
    ...

libfoo.dll: clean $(OBJS)
    ...


bar.o: bar_$(OS).c bar.h
    ...

Итак, когда вы набираете make libfoo.so, я ожидаю, что сначала он установит OS = LINUX. Затем, когда он достигает bar.o (это зависимость от libfoo), он должен знать, какой bar_$(OS).c использовать. Однако я получаю сообщение об ошибке:

make: *** No rule to make target `bar_.c', needed by bar.o. Stop.

Что говорит мне, что когда он пытается создать bar.o, $(OS) не устанавливается. Но не должно ли это быть первым, что происходит, когда я пытаюсь создать libfoo.so, и это правило оценивается?

Ответы [ 3 ]

2 голосов
/ 07 декабря 2011

Целевые переменные доступны в теле правила, а не в его предварительных условиях.Но даже если бы вы могли заставить это работать, вы бы напрашивались на неприятности: если вы создадите одну библиотеку, а затем другую, Make не сможет узнать, что bar.o, созданный для первого, неправильныйвторой и не должен использоваться.

Есть несколько способов получить желаемый эффект, но ни один не идеален.Я бы предложил использовать два разных имени объектных файлов, например bar_unix.o и bar_windows.o.

0 голосов
/ 08 декабря 2011

Если вы хотите установить переменную, специфичную для цели, и затем сделать эту переменную доступной вне тела этого правила, вы можете рекурсивно вызвать Makefile после экспорта переменной:

OBJS ?= foo.o                    # Use ? so it isn't blown away on recursive call

libfoo.so: OS = LINUX
libfoo.so: OBJS += linux_only.o
libfoo.so:
    $(MAKE) -s build_libfoo_linux

build_libfoo_linux: $(OBJS)
    @echo "OS = $(OS)"           # Should print "OS = LINUX"

export OS                        # Can be anywhere

Вы должны не забыть экспортировать переменные, которые вы хотите "сохранить" после рекурсивного вызова make. А также, как показано выше, если вы добавляете какие-либо переменные перед вызовом, вы захотите сделать их начальное присваивание с помощью ?=, чтобы они не устанавливались во второй раз.

0 голосов
/ 07 декабря 2011

Вы можете определить ОС, используя uname, а затем условно скомпилировать. Это объясняет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...