从Makefile中的$ @获取文件名

时间:2019-12-22 18:08:45

标签: c++ bash makefile

当所有cpp文件都在一个目录中时,此makefile很好用。 创建子目录后,由于缺少子目录,因此无法创建* .o文件:

目录结构

export default class Routes extends React.Component<props>{
  render() {
    return (
      <IonRouterOutlet id="main" contextMenu="main">

        <Route exact path="/Controller" render={() => (
          this.props.isLoged
            ? <Redirect to="/Home" />
            : <Controller />
        )} />

        <Route exact path="/Login" render={() => (
          this.props.isLoged
            ? <Redirect to="/Controller" />
            : <Login />
        )} />

        <Route exact path="/CreateAccount" render={() => (
          this.props.isLoged
            ? <Redirect to="/Home" />
            : <CreateAccount />
        )} />

        <Route exact path="/Home" render={() => (
          this.props.isLoged
            ? <Home id={this.props.id} type={this.props.userData.type} />
            : <Redirect to="/Login" />
        )} />

        <Route exact path="/AdminCompanies" render={() => (
          this.props.isLoged
            ? <AdminCompanies />
            : <Redirect to="/Login" />
        )} />

        <Route exact path="/FinancialState" render={() => (
          this.props.isLoged
            ? <ControllerUploadFiles id={this.props.id} targetDb="financial_state" title="Estados Financieros" />
            : <Redirect to="/Login" />
        )} />

        <Route exact path="/Rut" render={() => (
          this.props.isLoged
            ? <ControllerUploadFiles id={this.props.id} targetDb="register_unique_tribute" title="Registro Unico Tributario" />
            : <Redirect to="/Login" />
        )} />

        <Route exact path="/Settings" render={() => (
          this.props.isLoged
            ? <Settings id={this.props.id} accountData={this.props.userData} />
            : <Redirect to="/Login" />
        )} />

        {/* Ingreso de la cuenta del tipo cliente */}
        <Route exact path="/LoginClient" render={() => (
          this.props.isLoged
            ? <Redirect to="/Controller" />
            : <LoginClient />
        )} />

        {/* RUTAS DE LOS CLIENTES */}
        <Route exact path="/MyAccountans" render={() => (
          this.props.isLoged
            ? <Redirect to="/Home" />
            : <MyAccountants id={this.props.id} />
        )} />

        <Route path="/" render={() => <Redirect to="/Controller" />} />

      </IonRouterOutlet>
    );
  }
}

Makefile

.
├── Makefile
├── README.md
├── src
│   ├── Adventurer
│   │   └── Adventurer.cpp
│   ├── Board
│   │   ├── AdventureTile.cpp
│   │   └── Board.cpp

此代码的示例输出是:

CC := g++ # This is the main compiler
SRCDIR := src
BUILDDIR := build
TARGET := bin/forbidden-island

SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -g -Wall
LIB := -lsfml-graphics -lsfml-window -lsfml-system 
INC := -I include


$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
# BUILDPATH=$($(BUILDDIR)/%.o) # missing step of creating subdirectories 
# OFILE=$(basename $@)
    @mkdir -p $(BUILDDIR)
    @echo " $(CC) $(CFLAGS) $(INC) -c -o $@ $<"; $(CC) $(CFLAGS) $(INC) -c -o $@ $<

如何更改命令,使其仅是o文件的名称而不是完整路径。使用特殊变量$ @。

g++ -g -Wall -I include -c -o build/Board/Board.o src/Board/Board.cpp src/Board/Board.cpp: In member function ‘AdventureTile Board::getTile(int, int)’: src/Board/Board.cpp:13:1: warning: no return statement in function returning non-void [-Wreturn-type] } ^ Assembler messages: Fatal error: can't create build/Board/Board.o: No such file or directory Makefile:23: recipe for target 'build/Board/Board.o' failed make: *** [build/Board/Board.o] Error 1 返回了(basename $@),但需要登机。o

================解决方案===============

Makefile失败,因为未创建子目录。 build/Board/Board行必须变为@mkdir -p $(BUILDDIR)才能解决此问题。

1 个答案:

答案 0 :(得分:0)

我真的不明白您的意思是如何更改命令,使其仅是o文件的名称 ...哪个命令?

使用配方创建不完全等于$@值的文件是不正确的。这就是make期望您创建的内容,如果您的食谱创建了其他文件,则这些内容将无法正常工作。

无论如何,GNU支持的功能为available here。您想要的是$(notdir $@)。但是,您甚至不需要它,因为目录($(@D)和文件($(@F))都有automatic variables的变体。