无论文件是否存在,都使用变量名运行目标

时间:2015-07-21 18:37:12

标签: makefile gnu-make

我正在使用GNU make来处理一些数据。当我尝试使用变量名运行目标时,make将运行该目标,无论目标文件是否已存在。请考虑以下public class Buscar extends Activity implements OnItemSelectedListener{ String año; String artista; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_buscar); Buscar(); Spinner spinnerBuscarAño = (Spinner) findViewById(R.id.añoSpinner); String[] añoBuscar = {"1995", "2000", "2005"}; spinnerBuscarAño.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, añoBuscar)); spinnerBuscarAño.setOnItemSelectedListener(this); Spinner spinnerBuscarArtista = (Spinner) findViewById(R.id.artistaSpinner); String[] artistaBuscar = {"Michael Jackson", "U2", "Depeche Mode"}; spinnerBuscarArtista.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, artistaBuscar)); spinnerBuscarArtista.setOnItemSelectedListener(this); } /* public void onItemSelected(AdapterView<?> parent, View view,int pos, long id) { switch (parent.getId()) { case R.id.añoSpinner: año = parent.getItemAtPosition(pos).toString(); break; case R.id.artistaSpinner: artista = parent.getItemAtPosition(pos).toString(); break; default: break; } } */ @Override public void onItemSelected(AdapterView<?> parent, View v, int position, long id){ // TODO Auto-generated method stub Spinner spinner = (Spinner) parent; if(spinner.getId() == R.id.añoSpinner) { año = parent.getItemAtPosition(position).toString(); } else if(spinner.getId() == R.id.artistaSpinner) { artista = parent.getItemAtPosition(position).toString(); } } @Override public void onNothingSelected(AdapterView<?> arg0) { // TODO Auto-generated method stub } public void Buscar() { Button buttonBuscar = (Button) findViewById(R.id.buscar); buttonBuscar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Toast.makeText(getApplicationContext(),artista, Toast.LENGTH_SHORT).show(); Intent intentBuscar = new Intent(Buscar.this, ListadoMusica.class); intentBuscar.putExtra("myaño", año); intentBuscar.putExtra("myartista", artista); startActivity(intentBuscar); } }); } }

Makefile

其中config.mk包含:

include config.mk

.PHONY : all
all : $(PG_DB).db

$(PG_DB).db : 
    createdb $(PG_DB) -U $(PG_USER)
    touch $@

当我运行MAKEFLAGS += --warn-undefined-variables SHELL := bash .SHELLFLAGS := -eu -o pipefail .DEFAULT_GOAL := all .DELETE_ON_ERROR: .SUFFIXES: PG_USER="foo" PG_DB="foo" 时,make会创建Postgres数据库,然后触摸文件make。但是,当我再次运行foo.db时,输出为:

make

这不应该发生!在这种情况下,我希望createdb "foo" -U foo createdb: database creation failed: ERROR: database "foo" already exists make : *** ["foo".db] Error 1 检查虚假目标make的先决条件,看看all已经存在,并立即退出而不做任何事情。

奇怪的是,这正是当我摆脱目标名称中的变量时发生的事情:

foo.db

当我使用此修改后的include config.mk .PHONY : all all : foo.db foo.db : createdb $(PG_DB) -U $(PG_USER) touch $@ 运行make时,我得到:

Makefile

这正是我的期望。

这里发生了什么?

1 个答案:

答案 0 :(得分:0)

问题不是来自变量,它来自变量值中的引号。 make在检查依赖项之前不会删除引号。所以它正在检查包含引号的文件"foo".db。命令touch "foo".dbshell解释,删除引号。因此,对于make,文件永远不会存在,并且您将始终遇到相同的问题。当您明确地放置依赖项时,将其设置为不包含引号的foo.db。它完全不同。

在config.mk中

,转动

PG_DB="foo"

进入

PG_DB=foo

它应该有用。我猜createdb是一个普通的shell命令,不关心引号。否则,您需要在调用命令之前添加它。