<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at
 
 http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 -->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    
    <parent>
      <groupId>org.apache.hama</groupId>
      <artifactId>hama-parent</artifactId>
      <version>0.7.0-SNAPSHOT</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.apache.hama</groupId>
    <artifactId>hama-pipes</artifactId>
    <version>0.7.0-SNAPSHOT</version>
    <name>pipes</name>
    <description>Apache Hama Pipes</description>
    <packaging>pom</packaging>

    <profiles>     
      <profile>
        <id>native</id>
        <activation>
          <activeByDefault>true</activeByDefault>
        </activation>
        <build>
          <plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-antrun-plugin</artifactId>
              <version>1.7</version>
              <executions>
                <execution>
                  <id>make</id>
                  <phase>compile</phase>
                  <goals><goal>run</goal></goals>
                  <configuration>
                    <target>
                      <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref="maven.plugin.classpath" />
                      <!-- Check if cmake is installed -->
                      <property environment="env" />
                      <if>
                        <or>
                          <available file="cmake" filepath="${env.PATH}" />
                          <!--  on Windows it can be Path, path -->
                          <available file="cmake" filepath="${env.Path}" />
                          <available file="cmake" filepath="${env.path}" />
                        </or>
                        <then>
                          <mkdir dir="${project.build.directory}/native" />
                          <property name="ant.hama.pipes.examples.install" value="${project.build.directory}/native" />
                          <exec executable="cmake" dir="${project.build.directory}/native" failonerror="true">
                            <arg line="${basedir}/src/ -DJVM_ARCH_DATA_MODEL=${sun.arch.data.model}" />
                          </exec>
                          <exec executable="make" dir="${project.build.directory}/native" failonerror="true">
                            <arg line="VERBOSE=1" />
                          </exec>
                          <!-- The second make is a workaround for HADOOP-9215.  It can
                               be removed when version 2.6 of cmake is no longer supported . -->
                          <exec executable="make" dir="${project.build.directory}/native" failonerror="true" />
                        </then>
                        <else>
                      		<echo>CMAKE is missing! Skipping native build!</echo>
                      		<property name="ant.hama.pipes.examples.install" value="" />
                        </else>
                      </if>
                    </target>
                    <exportAntProperties>true</exportAntProperties>
                  </configuration>
                </execution>
                <!-- TODO wire here native testcases
                <execution>
                  <id>test</id>
                  <phase>test</phase>
                  <goals>
                    <goal>test</goal>
                  </goals>
                  <configuration>
                    <destDir>${project.build.directory}/native/target</destDir>
                  </configuration>
                </execution>
                -->
              </executions>
              <dependencies>
                <dependency>
                  <groupId>ant-contrib</groupId>
                  <artifactId>ant-contrib</artifactId>
                  <version>20020829</version>
                </dependency>
              </dependencies>
            </plugin>
            <plugin>
              <groupId>org.codehaus.groovy.maven</groupId>
              <artifactId>gmaven-plugin</artifactId>
              <version>1.0</version>
              <executions>
                <execution>
                  <phase>process-test-resources</phase>
                  <goals><goal>execute</goal></goals>
                  <configuration>
                    <source>
                      System.setProperty("hama.pipes.examples.install", project.properties['ant.hama.pipes.examples.install']);
                    </source>
                  </configuration>
                </execution>
              </executions>
            </plugin>
          </plugins>
        </build>
      </profile>
    </profiles>
<!--
    <build>
      <plugins>
       <plugin>
          <artifactId>maven-antrun-plugin</artifactId>
          <executions>
            <execution>
              <id>compile</id>
              <phase>generate-sources</phase>
              <goals>
                <goal>run</goal>
              </goals>
              <configuration>
                <target>
                  <mkdir dir="${basedir}/../target/native" />
                  <copy toDir="${basedir}/../target/native">
                    <fileset dir="${basedir}/src/main/native" />
                  </copy>
                </target>
              </configuration>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>
-->
</project>
