1

1 つのルールを同時に 2 つのファイルに依存させ、それらのファイルのいずれかが変更されたときにルールを 1 回だけ実行することは可能ですか?

SASS ソース ファイルのコンパイルを Makefile に追加しています。コンパスでコンパイルしましたが、ソース フォルダーと宛先フォルダーが指定された独自の構成があります。コンパスはパラメーターなしで実行され、変更されたすべての SASS ファイルを対応する CSS ファイルにコンパイルします。

2 つの SASS ファイルがあるとします。

folder1/file1.scss
folder2/file2.scss

両方のファイルが変更されている場合、compass を 1 回だけ実行すると、両方のファイルがコンパイルされます。Compass を 2 回実行する必要はありません。いずれかまたは両方のファイルが変更された場合にコンパイルを 1 回だけ実行できる Makefile を作成できますか? 次のように言います。

folder_out1/file1.css folder_out2/file2.css: folder1/file1.scss folder2/file2.scss
  compass compile

編集- FreeBSD で動作する修正済みスクリプト (いくつかの小さな変更を加えたもの):

#!/usr/bin/env bash

# Start fresh: delete all files and folders
rm -rf folder folder_out Makefile.mock mock_compass
# Create the input folder and files
mkdir folder
echo 1 > folder/file1.scss
echo 2 > folder/file2.scss

# Create mock compass command that creates output directories and copies
# input files to output files without transforming them
echo '
#!/usr/bin/env bash

if ! [ -d folder_out ]; then
    mkdir folder_out
fi
cp folder/file1.scss folder_out/file1.css
cp folder/file2.scss folder_out/file2.css' > ./mock_compass
chmod +x mock_compass

# Create the Makefile
echo -e '
# Disable implicit rules to simplify debugging output
.SUFFIXES:
%: %,v
%: RCS/%
%: RCS/%,v
%: s.%
%: SCCS/s.%

folder_out/file1.css folder_out/file2.css: folder/file1.scss folder/file2.scss
\t@echo Running compass
\t./mock_compass
' > Makefile.mock

# Test it!

echo 'Initial build:'
gmake -f Makefile.mock
echo

echo 'Changing only file1'
touch folder/file1.scss
gmake -f Makefile.mock
echo

echo 'Changing only file2'
touch folder/file2.scss
gmake -f Makefile.mock
echo

echo 'Changing both'
touch folder/file1.scss folder/file2.scss
gmake -f Makefile.mock
echo
4

1 に答える 1

2

はい、これらの 2 行だけでも、目的を正確に実行するための適切な Makefile です。

ただし、これを Mac で行っている可能性はありますか? 残念ながら、Mac ファイルシステムには 1 秒のファイル タイムスタンプしか解決されないため、このような状況では Make が大混乱を招く可能性があります。

テストスクリプトは次のとおりです。

#!/bin/bash

# Start fresh: delete all input and output folders
rm -rf folder{1,2,_out{1,2}}
# Create input folders and files
mkdir folder1
mkdir folder2
echo 1 > folder1/file1.scss
echo 2 > folder2/file2.scss

# Create mock compass command that creates output directories and copies
# input files to output files without transforming them
echo '
if ! [ -d folder_out1 ]; then
    mkdir folder_out{1,2}
fi
cp folder1/file1.scss folder_out1/file1.css
cp folder2/file2.scss folder_out2/file2.css' > ./mock_compass
chmod +x mock_compass

# Create the Makefile
echo '
# Disable implicit rules to simplify debugging output
.SUFFIXES:
%: %,v
%: RCS/%
%: RCS/%,v
%: s.%
%: SCCS/s.%

folder_out1/file1.css folder_out2/file2.css: folder1/file1.scss folder2/file2.scss
    @echo Running compass
    ./mock_compass
' > Makefile.mock

# Test it!

echo 'Initial build:'
make -f Makefile.mock
echo

echo 'Changing only file1'
touch folder1/file1.scss
make -f Makefile.mock
echo

echo 'Changing only file2'
touch folder2/file2.scss
make -f Makefile.mock
echo

echo 'Changing both'
touch folder1/file1.scss folder2/file2.scss
make -f Makefile.mock
echo

技術的にはすべて正しいのですが、Mac で実行すると、正しくない出力が得られます。

Initial build:
Running compass
./mock_compass

Changing only file1
make[1]: `folder_out1/file1.css' is up to date.

Changing only file2
make[1]: `folder_out1/file1.css' is up to date.

Changing both
make[1]: `folder_out1/file1.css' is up to date.

入力ファイルは、出力ファイルが作成された後に変更されますが、同じ秒内に変更されるため、それらの作成順序はディスクに保存されません。Make を再実行すると、両方でまったく同じタイムスタンプが表示され、それらが最新であると見なされます。これを確認するls -lTには、スクリプトに呼び出しを追加し、-dMake run にフラグを追加します。

ハックな回避策の 1 つは、mock_compass呼び出しを次のように変更することです。

./mock_compass && sleep 1 # mac timestamp resolution is 1 second :(

これにより、テスト スクリプトは正しい出力を生成します。

Initial build:
Running compass
./mock_compass && sleep 1 # mac timestamp resolution is 1 second :(

Changing only file1
Running compass
./mock_compass && sleep 1 # mac timestamp resolution is 1 second :(

Changing only file2
Running compass
./mock_compass && sleep 1 # mac timestamp resolution is 1 second :(

Changing both
Running compass
./mock_compass && sleep 1 # mac timestamp resolution is 1 second :(

だけでなく、スクリプトの実行時間が 0 秒から 4 秒に増加します :'(

これに対するより良い回避策がある場合は、お知らせください。

于 2013-01-28T18:16:02.823 に答える