为 elixir 项目编译牛仔时出现语法错误

Posted

技术标签:

【中文标题】为 elixir 项目编译牛仔时出现语法错误【英文标题】:Syntax error when compiling cowboy for elixir project 【发布时间】:2021-03-09 14:50:40 【问题描述】:

我有一个构建 elixir 项目的 Dockerfile。在这里,我编译了erlangelixir 来自源代码。之后我只运行docker build --build-arg ... new-image .,它可以正常工作,没有任何错误。请看下文

FROM centos:8.2.2004

ARG APP_NAME
ARG APP_VSN
ARG MIX_ENV=prod

ENV APP_NAME=$APP_NAME \
    APP_VSN=$APP_VSN \
    MIX_ENV=$MIX_ENV

RUN yum -y update
RUN yum -y upgrade
RUN yum -y install \
          nodejs \ 
          git \
          gcc gcc-c++ make \
          ncurses-devel \
          cmake \
          openssl-devel \
          autoconf \
          zip \
          bzip2 \
          readline-devel \
          jq \
          npm \
          && yum clean all

ENV ERLANG_VERSION=21.1.1
ENV ELIXIR_VERSION=1.8.2
ENV RUBY_VERSION=2.4.3
ENV ERL_AFLAGS="-kernel shell_history enabled"

ARG DISABLED_APPS='megaco wx debugger jinterface orber reltool observer et'
ARG ERLANG_TAG=OTP-$ERLANG_VERSION
ARG ELIXIR_TAG=v$ELIXIR_VERSION

LABEL erlang_version=$ERLANG_VERSION erlang_disabled_apps=$DISABLED_APPS elixir_version=$ELIXIR_VERSION ruby_version=$RUBY_VERSION

RUN yum update -y && yum clean all
RUN yum reinstall -y glibc-common && yum clean all

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en

RUN yum -y install glibc-locale-source glibc-langpack-en
RUN localedef -i en_US -f UTF-8 en_US.UTF-8

RUN locale

# Install Erlang
RUN set -xe \
    cd /tmp \
    && git clone --branch $ERLANG_TAG --depth=1 --single-branch https://github.com/erlang/otp.git \
    && cd otp \
    && echo "ERLANG_BUILD=$(git rev-parse HEAD)" >> /info.txt \
    && echo "ERLANG_VERSION=$(cat OTP_VERSION)" >> /info.txt  \
    && for lib in $DISABLED_APPS ; do touch lib/$lib/SKIP ; done \
    && ./otp_build autoconf \
    && ./configure \
        --enable-smp-support \
        --enable-m64-build \
        --disable-native-libs \
        --enable-sctp \
        --enable-threads \
        --enable-kernel-poll \
        --disable-hipe \
    && make -j$(nproc) \
    && make install \
    && find /usr/local -name examples | xargs rm -rf \
    && ls -d /usr/local/lib/erlang/lib/*/src | xargs rm -rf \
    && rm -rf \
       /otp/* \
      /tmp/*

# Install Elixir
RUN cd /tmp \
    && git clone https://github.com/elixir-lang/elixir.git \
    && cd elixir

RUN git clone --branch $ELIXIR_TAG --depth=1 --single-branch https://github.com/elixir-lang/elixir.git \
    && cd elixir \
    && echo "ELIXIR_BUILD=$(git rev-parse HEAD)" >> /info.txt \
    && echo "ELIXIR_VERSION=$(cat VERSION)" >> /info.txt  \
    && make -j$(nproc) compile \
    && rm -rf .git \
    && make install \
    && cd / \
    && rm -rf \
      /tmp/*

RUN  mix local.rebar --force
RUN  mix local.hex --force

# This copies our app source code into the build container
COPY . .

RUN mix do deps.get, deps.compile, compile, phx.digest

RUN echo $MIX_ENV
RUN echo $APP_NAME
RUN echo $APP_VSN

RUN \
  mix release --verbose && \
  cp _build/$MIX_ENV/rel/$APP_NAME/releases/$APP_VSN/$APP_NAME.tar.gz $APP_DIR && \
  tar -xzf $APP_NAME.tar.gz && \
  rm $APP_NAME.tar.gz

构建成功完成,并创建了一个名为 new-image 的新映像。自然,我想将new-image 重新用于其他项目。因此,我从 new-image 创建了一个新的 Dockerfile,imported,并删除了构建 elixirerlang 的命令。认为没关系,因为我已经在早期构建期间编译了二进制文件,所以 elixir 和 erlang 二进制文件应该已经存在于构建中,对吧? Dockerfile 最终如下所示

FROM new-image # created above

ARG APP_NAME
ARG APP_VSN
ARG MIX_ENV=prod

ENV APP_NAME=$APP_NAME \
    APP_VSN=$APP_VSN \
    MIX_ENV=$MIX_ENV

RUN yum -y update
RUN yum -y upgrade
RUN yum -y install \
          nodejs \ 
          git \
          gcc gcc-c++ make \
          ncurses-devel \
          cmake \
          openssl-devel \
          autoconf \
          zip \
          bzip2 \
          readline-devel \
          jq \
          npm \
          && yum clean all

ENV ERLANG_VERSION=21.1.1
ENV ELIXIR_VERSION=1.8.2
ENV RUBY_VERSION=2.4.3
ENV ERL_AFLAGS="-kernel shell_history enabled"

ARG DISABLED_APPS='megaco wx debugger jinterface orber reltool observer et'
ARG ERLANG_TAG=OTP-$ERLANG_VERSION
ARG ELIXIR_TAG=v$ELIXIR_VERSION

LABEL erlang_version=$ERLANG_VERSION erlang_disabled_apps=$DISABLED_APPS elixir_version=$ELIXIR_VERSION ruby_version=$RUBY_VERSION

RUN yum update -y && yum clean all
RUN yum reinstall -y glibc-common && yum clean all

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en

RUN yum -y install glibc-locale-source glibc-langpack-en
RUN localedef -i en_US -f UTF-8 en_US.UTF-8

RUN locale

RUN  mix local.rebar --force
RUN  mix local.hex --force

# This copies our app source code into the build container
COPY . .

RUN mix do deps.get, deps.compile, compile, phx.digest

RUN echo $MIX_ENV
RUN echo $APP_NAME
RUN echo $APP_VSN

RUN \
  mix release --verbose && \
  cp _build/$MIX_ENV/rel/$APP_NAME/releases/$APP_VSN/$APP_NAME.tar.gz $APP_DIR && \
  tar -xzf $APP_NAME.tar.gz && \
  rm $APP_NAME.tar.gz

当我现在从它构建时,编译牛仔时出现以下语法错误。

All dependencies are up to date
===> Compiling ranch
===> Compiling telemetry
===> Compiling cowlib
===> Compiling cowboy
Compiling 28 files (.ex)

== Compilation error in file lib/phoenix-1.4.1/priv/templates/phx.gen.channel/channel.ex ==
** (SyntaxError) lib/phoenix-1.4.1/priv/templates/phx.gen.channel/channel.ex:1: syntax error before: '='
    (elixir) lib/kernel/parallel_compiler.ex:208: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6
The command '/bin/sh -c mix do deps.get, deps.compile, compile, phx.digest' returned a non-zero code: 1

附:我没有安装 ruby​​ 2.4.3,不明白为什么这里需要 ruby​​。这也是我第一次看到一个 erlang 项目。所以请对我放轻松。

编辑:添加模板文件 (lib/phoenix-1.4.1/priv/templates/phx.gen.channel/channel.ex)

defmodule <%= module %>Channel do
  use <%= web_module %>, :channel

  def join("<%= singular %>:lobby", payload, socket) do
    if authorized?(payload) do
      :ok, socket
    else
      :error, %reason: "unauthorized"
    end
  end

  # Channels can be used in a request/response fashion
  # by sending replies to requests from the client
  

【问题讨论】:

你能把文件的前几行贴出来吗:lib/phoenix-1.4.1/priv/templates/phx.gen.channel/channel.ex @7stud 根据您的要求编辑问题 【参考方案1】:

您正在尝试编译模板文件。模板文件包含不是长生不老药的语法。必须通过预处理器运行模板文件以删除 &lt;%= ... %&gt; 标记并用合法的长生不老药语法替换它们。请参阅长生不老药中的EEx。基本上,文件是一个字符串,可以通过 EEx 引擎运行,将这些标签替换为这些标签中包含的长生不老药代码的返回值。

【讨论】:

我同意你说的。只是我没有在我的第一个 Dockerfile 中进行任何 EEx 预处理,但它似乎工作正常。你能用更简单的方式解释一下吗,因为除了删除构建 elixir 和 erlang 的行之外,我没有进行任何更改。先前成功构建的模板文件已经存在

以上是关于为 elixir 项目编译牛仔时出现语法错误的主要内容,如果未能解决你的问题,请参考以下文章

keil5中编写代码时出现语法错误为什么无显示

尝试编译 reCAPTCHA 代码时出现 PHP 语法错误?

在 .vue 组件中编译方法时出现语法错误

通过 std::thread 将参数传递给函数时出现语法错误

使用 VS 2015 打开 VS 2017 项目时出现语法错误 [重复]

将 varchar 转换为 int 时出现语法错误