Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Использование оболочки Makefile и цикл по файловому массиву

Автор вопроса: benjistОтветов: 1

Мои знания о makefiles очень ржавые. В рамках этапа сборки я хочу:

  • Перебрать все файлы в каталоге "javalibs"
  • Для каждого файла .jar вызовите "jar xf jarfile", чтобы извлечь все классы из этого файла jar. Поскольку jar xf позволяет извлекать только в текущее местоположение, я должен перейти в определенный каталог

Так что это моя конечная цель, иметь все классы в каком-то определенном каталоге (обоснование этого в том, что позже я запускаю ProGuard из этих классов).

Моя проблема в том, что... ну... мои знания makefile отстой =). Это та часть, где я хочу перебрать эти файлы:

$(classes): $(all-javas) $(all-properties) $(alljars)
    @rm -rf $(stage1)
    @mkdir -p $(stage1)
#   cur_dir=$(shell basename $(CURDIR))
    jars=`find $(makefile_dir)/$(javalibs) -name *.jar`
#$(wildcard $(javalibs)/*.jar)
    for jar in $(jars) ; do  \
        (wd=$$(pwd); \
        cd "$$makefile_dir/$$stage1" ; \
        `jar xf "$$makefile_dir/$$jar"` ; \
        echo "jar xf $$makefile_dir/$$jar" ;) \
    done
#   cd $(cur_dir)
    $(javac) -d $(stage1) -sourcepath $(src) \
        -bootclasspath $(vm-build)/classpath $(javas)
    cp $(all-properties) $(stage1)/

Моим ожидаемым результатом было бы то, что вызов

jar xf "$$makefile_dir/$$jar"

На самом деле будет вызываться в оболочке. Вместо этого я просто получаю эхо этого цикла for при выполнении make-файла:

for jar in  ; do  \
        (wd=$(pwd); \
        cd "$makefile_dir/$stage1" ; \
        `jar xf "$makefile_dir/$jar"` ; \
        echo "jar xf $makefile_dir/$jar" ;) \
    done

Обратите внимание на отсутствующий массив выше: "for jar in".

Мой ожидаемый результат будет состоять в том, что в "баночках" есть массив, который зацикливается. Но, возможно, я не могу инициализировать массив таким образом?

Я прошу о какой-то помощи, чтобы помочь мне понять, как инициализировать массив из возвращаемого значения оболочки. И правильно ли мой синтаксис выше в противном случае.

Обновление: у меня никогда не работал предложенный ответ (но это может быть из-за меня). Но вместо этого я сделал это:

define stageLibraryJar
    (cd $(libraries) && jar xf $(1))
    echo Extrcated $(1) to libraries
    cd $(makefile_dir)

endef

.PHONY: build
build: prepare-libraries make-vm $(xcode-build)/$(release)/hello.app/hello

.PHONY: prepare-libraries
prepare-libraries:
    rm -rf $(libraries).classes
    mkdir -p $(libraries).classes
    @rm -rf  $(libraries)
    @mkdir -p  $(libraries)
    @rm -rf $(stage1)
    @mkdir -p $(stage1)
    $(foreach jar,$(library-jars), $(call stageLibraryJar,$(makefile_dir)/$(jar)))

Не уверен, что это лучший способ сделать это. Но это работает

makefilegnu-makegnu

Ответы

Ответ 1 · рейтинг 2 · Beta

Вы можете сделать это с помощью цикла оболочки внутри команды, но этот способ намного проще:

JARS := $(shell find $(makefile_dir)/$(javalibs) -name "*.jar")

$(info jar files are $(JARS))
# be sure this looks right before you proceed

MODULES := $(patsubst %.jar,%.module,$(JARS))  # "module" is just a name

all: $(MODULES)

.PHONY: $(MODULES)
$(MODULES): %.module :
    @cd $(makefile_dir)/$(stage1) ; jar xf $(makefile_dir)/$*.jar

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы