Как я могу скомпилировать определенные файлы и добавить флаги в Makefile, только если выбрана указанная цель c? - PullRequest
1 голос
/ 05 февраля 2020

В настоящее время я сталкиваюсь с проблемой при написании Makefile для проекта C.

В частности, мой проект должен иметь как минимум две цели Makefile (target_light и target_full), будучи target_light по умолчанию.

target_light должен скомпилировать все мои исходные файлы, кроме немногих, которые требуют установки внешней системы в системе (которые сохраняются в src/extra, для. c файлы и include/extra для файлов .h). target_full должен вместо этого скомпилировать все файлы, включая те, которые нуждаются во внешней библиотеке. Также следует добавить несколько флагов в CFLAGS и LDLIBS.

У меня сейчас есть Makefile, похожий на следующий:

EXECNAME=MyExecutable

CC=gcc

SRC_DIR=src
OBJ_DIR=obj

SRC_DIR_EXTERNAL_FILES=src/extra
OBJ_DIR_EXTERNAL_FILES=obj/extra

SRC=$(wildcard $(SRC_DIR)/*.c)
OBJ=$(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)

SRC_EXTERNAL_FILES=$(wildcard $(SRC_DIR_EXTERNAL_FILES)/*.c)
OBJ_EXTERNAL_FILES=$(SRC_EXTERNAL_FILES:$(SRC_DIR_EXTERNAL_FILES)/%.c=$(OBJ_DIR_EXTERNAL_FILES)/%.o)

CFLAGS += -Wall -O2 -Iinclude
LDLIBS += -lpthread -lm

.PHONY: all clean

all: target_light

target_light: CC=gcc
target_light_embedded: CC=x86_64-openwrt-linux-musl-gcc

target_light_debug: CFLAGS += -g
target_light_debug: target_light

target_light target_light_debug target_light_embedded: $(EXECNAME)

$(EXECNAME): $(OBJ_CC)
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    $(RM) $(OBJ_DIR)/*.o $(OBJ_DIR_EXTERNAL_FILES)/*.o
    $(RM) $(EXECNAME)
    -rm -rf $(OBJ_DIR)

В настоящее время я пытаюсь найти способ добавить target_full к этому Makefile, который также должен учитывать SRC_DIR_EXTERNAL_FILES OBJ_DIR_EXTERNAL_FILES SRC_EXTERNAL_FILES OBJ_EXTERNAL_FILES, чтобы скомпилировать дополнительные файлы только по запросу.

Как я могу это сделать операция? Есть ли хороший способ сделать это в Makefile?

Мой второй вопрос: как добавить одновременно флаги к CFLAGS и LDLIBS, только если выбран target_full ? Я попытался написать:

target_full: CFLAGS += -DENABLE_CODE_EXTERNAL_LIB -Iinclude/extra
    LDLIBS += -lext_lib

А затем изменив строку $(EXECNAME) в:

target_light target_light_debug target_light_embedded target_full: $(EXECNAME)

Но дополнительный флаг LDLIBS, кажется, всегда учитывается, даже когда target_light

Должен ли я сделать что-то вроде следующих строк, повторяя два раза target_full?

target_full: CFLAGS += -DENABLE_CODE_EXTERNAL_LIB -Iinclude/extra
target_full: LDLIBS += -lext_lib

Большое спасибо заранее.

1 Ответ

2 голосов
/ 05 февраля 2020

Если target_light и target_full совместно используют объектные файлы, то при сборке target_light он компилирует источники без target_full CFLAGS. Когда вы создаете target_full, он не перестраивает существующие объектные файлы с дополнительными CFLAGS.

Возможные решения:

  1. Сборка всех объектных файлов с target_full CFLAGS. Таким образом, объектные файлы могут совместно использоваться целевыми объектами.
  2. Создание объектных файлов для target_light и target_full с различными CFLAGS в разных каталогах. В этом случае объектные файлы не разделяются между целями.
...