使用CMake调用Makefile 项目

基本示例

如果项目是使用传统的Makefile构建的,并且您希望使用CMake调用这些Makefile,您可以使用CMake的add_custom_targetadd_custom_command命令来实现。

首先,创建一个CMakeLists.txt文件。然后,在其中使用add_custom_targetadd_custom_command来调用您的原始Makefile。

现在用一共示例来说明,假如有以下的项目结构

project/
├── build/
├── CMakeLists.txt
├── Makefile
└── src/
    ├── Makefile
    └── main.cc

这是一个简单的项目,其中src目录包含一个main.cc文件。接下来,我们需要编写两个Makefile。

  1. 在项目的根目录下创建一个Makefile:

    在项目的根目录下的Makefile中,您可以使用$(MAKE)命令来调用src目录下的Makefile。:

    # project/Makefile
    
    .PHONY: all
    
    all: call_src_makefile
    @echo %date% %time% - Running target 'all'
    
    call_src_makefile:
    $(MAKE) -C src
    
    clean:
      $(MAKE) -C src clean
    

    这个Makefile现在定义了两个目标:allcleanall目标依赖于build_src_makefile目标,当您在顶层目录中运行makemake all时,它会调用src目录下的Makefile来构建项目。同样,clean目标会调用src目录下的Makefile中的clean目标来清理构建产物。

  2. src目录下创建另一个Makefile:

    # project/src/Makefile
    
    CC = g++
    CFLAGS = -Wall -std=c++11
    
    TARGET = main
    SOURCES = main.cc
    
    all: $(TARGET)
    
    $(TARGET): $(SOURCES)
      $(CC) $(CFLAGS) $(SOURCES) -o $(TARGET)
    
    clean:
      rm -f $(TARGET)
    

    此Makefile负责编译main.cc并生成一个名为main的可执行文件。

  3. 创建一个简单的main.cc文件:

    // project/src/main.cc
    
    #include <iostream>
    
    int main() {
        std::cout << "Hello, world!" << std::endl;
        return 0;
    }
    
  4. 确保项目根目录下的CMakeLists.txt文件包含以下内容:

    cmake_minimum_required(VERSION 3.10)
    
    project(MyProject)
    
    add_custom_target(build_top_level_makefile
                      COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}
                      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
    
    add_custom_target(build_src_makefile
                      COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}/src
                      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src)
    
  5. 切换到build目录,并运行cmake

    cd build
    cmake ..
    

    这将在build目录下生成CMake的Makefile。

  6. build目录下运行make

    make build_top_level_makefile
    

    或者直接运行:

    make build_src_makefile
    

    这将使用src目录下的Makefile构建项目。

  7. 运行生成的可执行文件:

    ../src/main
    

说明:如何传递给具体的makefile文件

make -f 命令

make 是一个用于自动构建可执行程序和库的工具,它使用名为 Makefile 的文件,其中包含了一些规则和依赖来决定如何构建目标。

-fmake 的一个命令行选项,它允许你指定一个不同于默认的 Makefile 文件。默认情况下,make 命令会在当前目录下寻找一个名为 Makefile 的文件。如果你想使用一个不同的文件,比如 Makefile1,你可以使用 -f 选项指定它,如 make -f Makefile1

当你运行 make -f Makefile1 时,make 会读取 Makefile1 文件,并查找第一个目标(或者默认目标)。默认目标通常是文件的第一个目标,但也可以通过 .DEFAULT 特殊目标来显式设置。make 会尝试构建这个目标,并在需要时,根据 Makefile1 中定义的规则和依赖,构建其他目标。

如果你想构建 Makefile1 中定义的特定目标,你可以在 make -f Makefile1 命令后面添加目标名称,如 make -f Makefile1 targetname。在这种情况下,make 会尝试只构建 targetname,以及任何 targetname 依赖的目标。

总的来说,make -f 命令使你能够使用不同的 Makefile 文件,或者在同一个 Makefile 中构建不同的目标。

make include指令

Makefile 中,include 指令用于包含其他的 Makefile 文件。这个指令允许你将一个大的 Makefile 分割成多个小的,易于管理和重用的文件。

Makefile 文件中出现 include 指令时,make 将会读取并处理指定的文件,就像这些文件的内容直接插入到 include 指令的位置一样。这意味着被包含文件中的所有规则、目标、变量定义等都将被添加到主 Makefile 中。

被包含的 Makefile 文件中的规则和目标是独立的,它们不会因为被包含而改变。如果一个目标在多个被包含的 Makefile 中都有定义,或者在主 Makefile 和一个或多个被包含的 Makefile 中都有定义,那么 make 将会使用最后一个定义的规则。在处理 Makefile 时,make 会依次读取文件,所以最后读取的文件中的定义将覆盖之前的定义。

例如,如果你有以下的 Makefile

include Makefile1
include Makefile2

Makefile1Makefile2 中都定义了一个名为 target 的目标,那么 make target 将会使用 Makefile2 中的定义,因为 Makefile2 是最后被读取的。

然而,通常来说,为了避免混乱和不确定性,最好在 Makefile 文件中避免目标和规则的名字重复。如果你需要在多个 Makefile 中使用相同的目标名,可能需要重新考虑你的构建系统设计。

传递

make -C ${CMAKE_CURRENT_SOURCE_DIR}命令会在${CMAKE_CURRENT_SOURCE_DIR}目录下执行make,并寻找名为Makefile的文件来执行。在一个目录下通常只应有一个Makefile

如果${CMAKE_CURRENT_SOURCE_DIR}目录下有多个Makefile,那么通常需要使用不同的名称来区分它们,例如Makefile1Makefile2。在这种情况下,make -C ${CMAKE_CURRENT_SOURCE_DIR}命令将不知道应该执行哪个Makefile,除非你指定具体的文件名,例如make -f Makefile1 -C ${CMAKE_CURRENT_SOURCE_DIR}

因此,如果${CMAKE_CURRENT_SOURCE_DIR}目录下有多个Makefilemake -C ${CMAKE_CURRENT_SOURCE_DIR}命令默认会找到并执行名为Makefile的文件。如果有多个文件都叫Makefile,那么这个命令可能会出错,或者只执行其中一个Makefile,具体哪个可能取决于文件系统的行为。

Cmake传递lib给Makefile

将CMake引用的库连接到调用的Makefile中需要手动处理一些细节,但这是可行的。以下是一种可能的方法:

  1. 在您的CMakeLists.txt中,找到和引用的库相关的信息,包括库文件的路径和链接选项。例如,如果您使用find_packagetarget_link_libraries来引用库,那么您需要找到这些库的路径和链接选项。
  2. 创建一个新的Makefile变量,用于传递库信息给被调用的Makefile。例如,您可以创建一个名为LIBS的变量,并将CMake找到的库信息赋值给它。
  3. 修改被调用的Makefile,使其能够接收并使用从CMake传递的库信息。在Makefile中,您需要使用$(LIBS)变量来添加库链接选项。

例如,您的CMakeLists.txt文件可能如下所示:

cmake_minimum_required(VERSION 3.10)
project(MyProject)

# Find your libraries using find_package or other methods
find_package(YourLibrary REQUIRED)

# ...

add_custom_target(build_with_libs
                  COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR} LIBS="${YourLibrary_LIBRARIES}"
                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

接下来,修改您的Makefile,以便它能够接收和使用LIBS变量。例如:

# Your original Makefile content

# Add the library information passed from CMake
LDFLAGS += $(LIBS)

# ...

这样,当您通过CMake调用Makefile时,CMake找到的库信息将被传递给Makefile,并用于链接过程。

Cmake传递参数给Makefile,比如make clean

我的目的是希望通过cmake生成的makefile直接传递参数给我的主makefile

修改CMakeLists.txt

以下是一个在CMakeLists.txt中添加自定义目标的示例:

cmake_minimum_required(VERSION 3.10)

project(MyProject)
find_library(MY_LIBRARY my_library)
find_path(MY_INCLUDE_DIR my_header.h)

function(add_custom_make_target TARGET_NAME EXTRA_ARGS)
  add_custom_target(${TARGET_NAME}
                    COMMAND ${CMAKE_MAKE_PROGRAM} -C ${CMAKE_SOURCE_DIR} ${TARGET_NAME} ${EXTRA_ARGS}
                    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
endfunction()

add_custom_target(default_target ALL
                  COMMAND MY_LIBRARY=${MY_LIBRARY} MY_INCLUDE_DIR=${MY_INCLUDE_DIR} ${CMAKE_MAKE_PROGRAM} -C ${CMAKE_SOURCE_DIR}
                  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})

#add_custom_make_target(clean)
add_custom_make_target(clean_all "")
add_custom_make_target(clean_global "")
add_custom_make_target(generate "MY_LIBRARY=${MY_LIBRARY} MY_INCLUDE_DIR=${MY_INCLUDE_DIR}")
add_custom_make_target(make_parallel "")
add_custom_make_target(preprocess "")
add_custom_make_target(check_dups "")
add_custom_make_target(flat_src "")
add_custom_make_target(mak "")

Windows下使用Cmake调用Makefile

在Windows上使用CMake调用Makefile是可行的,但需要考虑一些额外因素。首先,Windows上没有默认的Make工具,因此您需要安装GNU Make或其他Make实现。GNU Make通常可以通过安装MinGW或Cygwin获得。

然后,确保将Make工具添加到系统的PATH环境变量中,以便CMake可以找到并调用它。当您在Windows上使用CMake时,生成的构建系统可能是Visual Studio解决方案或NMake文件。因此,调用Makefile时,您需要确保使用了正确的构建系统。

例如,假设您已经安装了GNU Make并将其添加到了系统PATH中。在CMakeLists.txt中,您可以创建一个自定义目标,以便在Windows上调用Makefile:

cmake_minimum_required(VERSION 3.10)
project(MyProject)

# ...

if(WIN32)
    add_custom_target(build_with_makefile
                      COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}
                      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endif()

在Windows上使用CMake生成构建文件时,您可能需要指定一个生成器。例如,您可以使用命令行选项-G指定生成器:

cmake -G "MinGW Makefiles" ..

这将生成适用于MinGW Make的Makefile。然后,您可以使用cmake --build . --target build_with_makefile命令来调用CMakeLists.txt中定义的自定义目标,进而调用您的原始Makefile。

注意,Visual Studio解决方案使用MSBuild作为其构建系统,而不是Make。当您在Windows上使用CMake生成Visual Studio解决方案时,CMake会生成一个.sln文件和多个.vcxproj文件,这些文件与MSBuild一起工作。在这种情况下,直接在CMakeLists.txt中调用原始的Makefile是不合适的。

不过,如果您仍然需要在Visual Studio解决方案中调用Makefile,可以创建一个自定义的构建事件。您可以在Visual Studio项目属性中设置这个事件,以在构建过程的某个特定阶段调用Makefile。具体操作如下:

  1. 在Visual Studio中打开您的项目。
  2. 右键点击项目名称,选择“属性”。
  3. 在“配置属性”下展开“生成事件”。
  4. 在“预生成事件命令行”、“预链接事件命令行”或“后生成事件命令行”中输入执行Makefile所需的命令。例如,您可以输入make -C "$(ProjectDir)",其中$(ProjectDir)是Visual Studio的一个宏,代表项目目录的路径。
  5. 点击“应用”,然后点击“确定”。

现在,在Visual Studio构建解决方案时,将在指定的构建阶段执行Makefile。需要注意的是,这种方法与CMake在很大程度上是分离的,因此您可能需要手动管理库依赖关系和其他构建设置。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
第一部分、概述...............................................................................................................................6 第二部分、关于程序的编译和链接...............................................................................................6 第三部分、 Makefile 介绍 ............................................................................................................7 一、 Makefile的规则 ..............................................................................................................7 二、一个示例...........................................................................................................................8 三、 make是如何工作的........................................................................................................9 四、 makefile使用变量....................................................................................................10 五、让make自动推导..........................................................................................................11 六、另类风格的makefile....................................................................................................12 七、清空目标文件的规则.....................................................................................................13 第四部分、 Makefile 总述 ..........................................................................................................13 一、 Makefile里有什么? ....................................................................................................13 1、显式规则。 ..............................................................................................................14 2、隐晦规则。 ..............................................................................................................14 3、变量的定义。 ..........................................................................................................14 4、文件指示。 ..............................................................................................................14 5、注释。 ......................................................................................................................14 二、 Makefile的文件名 ........................................................................................................15 三、引用其它的Makefile ....................................................................................................15 四、环境变量 MAKEFILES................................................................................................16 五、 make的工作方式..........................................................................................................16 第五部分、书写规则.....................................................................................................................17 一、规则举例.........................................................................................................................17 二、规则的语法.....................................................................................................................17 三、在规则中使用通配符.....................................................................................................18 四、文件搜寻.........................................................................................................................19 五、伪目标.............................................................................................................................20 六、多目标.............................................................................................................................22 七、静态模式.........................................................................................................................22 八、自动生成依赖性.............................................................................................................24 第六部分 书写命令.......................................................................................................................25 一、显示命令.........................................................................................................................26 二、命令执行.........................................................................................................................26 三、命令出错.........................................................................................................................27 四、嵌套执行make..............................................................................................................28 五、定义命令包.....................................................................................................................30 第七部分 使用变量.......................................................................................................................30 一、变量的基础.....................................................................................................................31 二、变量中的变量.................................................................................................................32 三、变量高级用法.................................................................................................................34 四、追加变量值.....................................................................................................................37 五、 override 指示符 ..........................................................................................................37 六、多行变量.........................................................................................................................38 第 2 页共 78 页 2005 年 10 月 14 日整理:祝冬华跟我一起写 Makefile 作者:陈皓 七、环境变量.........................................................................................................................38 八、目标变量.........................................................................................................................39 九、模式变量.........................................................................................................................40 第八部分 使用条件判断...............................................................................................................40 一、示例.................................................................................................................................40 二、语法.................................................................................................................................42 第九部分 使用函数.......................................................................................................................43 一、函数的调用语法.............................................................................................................44 二、字符串处理函数.............................................................................................................44 1、 subst .......................................................................................................................44 2、 patsubst.................................................................................................................45 3、 strip .........................................................................................................................45 4、 findstring ...............................................................................................................46 5、 filter.........................................................................................................................46 6、 filter-out.................................................................................................................46 7、 sort ..........................................................................................................................47 8、 word ........................................................................................................................47 9、 wordlist ..................................................................................................................47 10、 words....................................................................................................................47 11、 firstword..............................................................................................................48 12、字符串函数实例....................................................................................................48 三、文件名操作函数.............................................................................................................48 1、 dir.............................................................................................................................48 2、 notdir ......................................................................................................................48 3、 suffix .......................................................................................................................49 4、 basename..............................................................................................................49 5、 addsuffix................................................................................................................49 6、 addprefix ...............................................................................................................49 7、 join...........................................................................................................................50 四、 foreach 函数................................................................................................................50 五、 if 函数 ............................................................................................................................50 六、 call函数..........................................................................................................................51 七、 origin函数 .....................................................................................................................51 “undefined” .................................................................................................................52 “default”.......................................................................................................................52 “file”...............................................................................................................................52 “command line”.........................................................................................................52 “override” ....................................................................................................................52 “automatic”.................................................................................................................52 八、 shell函数 .......................................................................................................................53 九、控制make的函数..........................................................................................................53 1、 error ........................................................................................................................53 2、 warning ..................................................................................................................54 第十部分 make 的运行..............................................................................................................54 第 3 页共 78 页 2005 年 10 月 14 日整理:祝冬华跟我一起写 Makefile 作者:陈皓 一、 make的退出码..............................................................................................................54 二、指定Makefile ................................................................................................................54 三、指定目标.........................................................................................................................55 “all” ................................................................................................................................56 “clean” ..........................................................................................................................56 “install” .........................................................................................................................56 “print” ...........................................................................................................................56 “tar” ...............................................................................................................................56 “dist”..............................................................................................................................56 “TAGS” ..........................................................................................................................56 “check”和“test” ..........................................................................................................56 四、检查规则.........................................................................................................................57 五、 make的参数..................................................................................................................57 第十一部分 隐含规则...................................................................................................................61 一、使用隐含规则.................................................................................................................61 二、隐含规则一览.................................................................................................................62 1、编译C程序的隐含规则 ...........................................................................................63 2、编译C++程序的隐含规则.....................................................................................63 3、编译Pascal程序的隐含规则..................................................................................63 4、编译Fortran/Ratfor程序的隐含规则..................................................................63 5、预处理Fortran/Ratfor程序的隐含规则..............................................................63 6、编译Modula-2 程序的隐含规则...........................................................................63 7、汇编和汇编预处理的隐含规则 ..............................................................................64 8、链接Object文件的隐含规则 .................................................................................64 9、 Yacc C程序时的隐含规则 .....................................................................................64 10、 Lex C程序时的隐含规则.....................................................................................64 11、 Lex Ratfor程序时的隐含规则 ...........................................................................65 12、从C程序、 Yacc文件或Lex文件创建Lint库的隐含规则 ..................................65 三、隐含规则使用的变量.....................................................................................................65 1、关于命令的变量。 ..................................................................................................65 2、关于命令参数的变量 ..............................................................................................66 四、隐含规则链.....................................................................................................................67 五、定义模式规则.................................................................................................................68 1、模式规则介绍 ..........................................................................................................68 2、模式规则示例 ..........................................................................................................69 3、自动化变量 ..............................................................................................................70 4、模式的匹配 ..............................................................................................................72 5、重载内建隐含规则 ..................................................................................................72 六、老式风格的"后缀规则" .................................................................................................73 七、隐含规则搜索算法.........................................................................................................74 第十二部分 使用make更新函数库文件....................................................................................75 一、函数库文件的成员.........................................................................................................75 二、函数库成员的隐含规则.................................................................................................75 三、函数库文件的后缀规则.................................................................................................76 第 4 页共 78 页 2005 年 10 月 14 日整理:祝冬华跟我一起写 Makefile 作者:陈皓 四、注意事项.........................................................................................................................76 第十三部分 后序...........................................................................................................................77

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泡沫o0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值