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

Мои знания о 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)))

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


person benjist    schedule 19.07.2014    source источник


Ответы (1)


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

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
person Beta    schedule 19.07.2014
comment
Спасибо, действительно выглядит намного чище. Однако, что бы я ни пытался, мои МОДУЛИ всегда пусты. Хм. Завтра попробую снова. - person benjist; 20.07.2014
comment
Пожалуйста, смотрите мой обновленный вопрос. У меня никогда не получалось, чтобы это работало, но, возможно, это только из-за меня. - person benjist; 22.07.2014
comment
@benjist: Что было в JARS? - person Beta; 23.07.2014
comment
Я только что переименовал JARS в библиотечные банки. Он содержит список путей относительно каталога makefile (ранее я также использовал абсолютный путь для вашего кода). Теперь определяется как: library-jars = $(shell find $(javalibs) -name '*.jar') - person benjist; 23.07.2014
comment
@benjist: И что там было? Можете ли вы привести один или два примера этих путей? - person Beta; 23.07.2014
comment
javalibs/jetty-all-9.2.1.v20140609.jar javalibs/servlet-api-3.1.0.jar - person benjist; 23.07.2014
comment
@benjist: И MODULES был пуст, используя make-файл выше? Это очень странно. - person Beta; 24.07.2014
comment
Да. Но мой makefile немного сложнее, и мне пришлось его немного изменить. То есть, может быть, это была моя вина, что это не сработало. Я, возможно, попробую еще раз. Но так как пока все работает, оставлю то, что есть. Но вы привели меня в нужное русло, поэтому я голосую за. - person benjist; 24.07.2014
comment
Я приму этот ответ тогда, когда у меня заработает предложенное вами решение. - person benjist; 24.07.2014