首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >cmake:在Makefile中运行ant脚本

cmake:在Makefile中运行ant脚本

作者头像
10km
发布2019-05-25 22:35:47
1.6K0
发布2019-05-25 22:35:47
举报
文章被收录于专栏:10km的专栏10km的专栏

版权声明:本文为博主原创文章,转载请注明源地址。 https://cloud.tencent.com/developer/article/1433746

Apache Ant,是一个将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具,在Java开发环境中应用非常广泛。

CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake,在c/c++跨平台开发中应用非常广泛 。

有的时候,我们项目是java/c/c++混合代码,这时可能就需要同时应用上述两种工具。

在项目初始阶段,java和c/c++代码可以分别用ant和cmake写脚本进行编译,但当项目越来越成形,越来越复杂的时候,再分别手工编译就非常容易出错。

如果能统一用一个工具(ant或cmake)进行编译,就可以提高工作效率减少编译环节出错的机率。

很久以前写过一个博客《ant调用make实现Makefile编译》,可以通过shell脚本方式,让ant执行Makefile编译,可以实现用ant统一编译项目代码的需求。

反过来,cmake也可以生成可以执行ant脚本的Makefile,以用cmake统一编译项目代码的需求。

cmake实现在Makefile中执行ant脚本是通过add_custom_commandadd_custom_target命令来完成的。add_custom_command允许用户将任何一个可执行文件定义成类似cmake-command的custom_command语句。而add_custom_target可以定义一个依赖于custom_command的target。

好吧,说起来好绕口,还是用例证来说明吧。

下面这段代码是cmake脚本中的片段,用于在cmake脚本中执行ant脚本编译java代码。

# 定义一个是否编译java代码的开关,默认不编译
option(BUILD_JAVA "Build the cassdk_jni jar (Java)" OFF)
if(BUILD_JAVA)
    # 执行find_program 命令在 环境变量(PATH)中查找ant可执行程序
    find_program (ANT_CMD ant)
    if(NOT ANT_CMD)
        // 如果没有找到ant.exe则报错退出
        message(FATAL_ERROR "NOT FOUND ant")
    endif()
    # 执行file命令生成java编译依赖文件列表,当列表中的java代码文件被修改时,就会执行ant脚本编译java代码
    # GLOB_RECURSE指定递归搜索子目录
    file(GLOB_RECURSE  java_srcs "${CMAKE_CURRENT_SOURCE_DIR}/src/*.java")
    # 定义输出的jar包名及位置
    set ( CASSDK_JAR ${CMAKE_CURRENT_SOURCE_DIR}/build/jar/cassdk_jni.jar)
    # 执行 ant jar命令 (当然 ant脚本build.xml中要有名为'jar'的target)
    # 编译 java 代码,并将java代码编译并生成jar包
    add_custom_command(
      OUTPUT ${CASSDK_JAR} 
      COMMAND ${ANT_CMD} jar
      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
      DEPENDS ${java_srcs} # 依赖的java源码改变时会执行此命令
      COMMENT "run ant jar -> cassdk_jni.jar"
    )
    # 创建自定义target
    add_custom_target(CASSDKJavaJar ALL
      DEPENDS ${CASSDK_JAR} # 依赖add_custom_command输出的jar包
      COMMENT "building cassdk_jni.jar"
    )
    # 安装jar包到 jar目录下
    install(FILES ${CASSDK_JAR}
      DESTINATION jar COMPONENT JavaModule
    )
endif(BUILD_JAVA)        

上面代码中使用ant脚本比较简单,也一并贴出来

build.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="cassdk_jni">
    <property environment="env"/>
    <property name="debuglevel" value="source,lines,vars"/>
    <property name="target" value="1.6"/>
    <property name="source" value="1.6"/>
    <property name="build.dir" value="${basedir}/build" />
    <property name="jar.dir" value="${build.dir}/jar" />
    <property name="release.dir" value="${basedir}/../release/jar" />
    <property name="jarname" value="${ant.project.name}.jar" />
    <path id="cassdk_jni.classpath">
        <pathelement location="build/classes"/>
    </path>
    <target name="init">
        <mkdir dir="build/classes"/>
        <copy includeemptydirs="false" todir="build/classes">
            <fileset dir="src">
                <exclude name="**/*.launch"/>
                <exclude name="**/*.java"/>
            </fileset>
        </copy>
        <copy includeemptydirs="false" todir="build/classes">
            <fileset dir="test">
                <exclude name="**/*.launch"/>
                <exclude name="**/*.java"/>
            </fileset>
        </copy>
    </target>
    <target name="clean" description="清除生成的文件">
        <delete dir="${build.dir}"/>
    </target>
    <target depends="clean" name="cleanall" description="清除所有生成的文件(包含release)">
         <delete dir="${release.dir}"/>
    </target>
    <target depends="init" name="build" description="编译代码">
        <echo message="${ant.project.name}: ${ant.file}"/>
        <javac debug="true" debuglevel="${debuglevel}" destdir="build/classes" includeantruntime="false" source="${source}" target="${target}" encoding="utf-8">
            <src path="src"/>
            <classpath refid="cassdk_jni.classpath"/>
        </javac>
    </target>
    <target depends="clean,build" name="rebuild" description="重新编译代码"/>
    <target name="jar" depends="build" description="生成jar包">
        <echo message="生成${jar.dir}/${jarname}" />
        <jar destfile="${jar.dir}/${jarname}">
            <fileset dir="${build.dir}/classes" />
        </jar>
    </target>
    <target name="release" depends="clean,jar" description="复制jar包到release目录">
        <copy includeemptydirs="false" todir="${release.dir}">
            <fileset dir="${jar.dir}">
                <include name="**/*.jar"/>
            </fileset>
        </copy>
    </target>
</project>

参考资料:

https://cmake.org/cmake/help/v3.1/command/add_custom_command.html

https://cmake.org/cmake/help/v3.1/command/add_custom_target.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年07月05日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档