Makefile问答之02 预处理器与宏

2024-09-07 00:36
文章标签 02 问答 处理器 makefile

本文主要是介绍Makefile问答之02 预处理器与宏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

GCC Makefile中,怎样设定预处理器名称

在 GCC 的 Makefile 中,预处理器(preprocessor)的名称通常是 cpp(C PreProcessor),但在实际的 Makefile 中,我们一般是通过 gcc 命令来调用预处理器,而不是直接调用 cpp。不过,你可以通过设置 CPP 变量来显式指定预处理器名称和选项。以下是如何在 Makefile 中进行设置和使用的示例。

示例 Makefile

# 编译器

CC = gcc

# 预处理器

CPP = cpp

# 编译选项

CFLAGS = -Wall -O2 -Iinclude

# 链接选项

LDFLAGS =

# 需要链接的库

LDLIBS =

# 目标文件

TARGET = my_program

# 查找所有源文件

SRCS = $(shell find src -name '*.c')

# 自动生成对应的目标文件名

OBJS = $(SRCS:.c=.o)

# 默认目标

all: $(TARGET)

# 链接

$(TARGET): $(OBJS)

    $(CC) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS)

# 编译

%.o: %.c

    $(CC) $(CFLAGS) -c $< -o $@

# 预处理

%.i: %.c

    $(CPP) -E $< -o $@

# 清理

clean:

    rm -f $(TARGET) $(OBJS)

说明

  1. 设定预处理器名称
    CPP = cpp




  2. 这里设置了 CPP 变量,指定了预处理器的名称。在实际使用中,cpp 是 GNU 编译器集合的 C 预处理器。你可以将其替换为其他预处理器的名称(如果有的话),但通常情况下使用默认的 cpp 就足够了。
  3. 预处理规则
    %.i: %.c
  4.     $(CPP) -E $< -o $@




  5. 这个规则用于从 .c 文件生成 .i 文件,即预处理后的文件。$< 是源文件,$@ 是目标文件。-E 选项告诉 cpp 只进行预处理,不进行编译。
  6. 编译规则
    %.o: %.c
  7.     $(CC) $(CFLAGS) -c $< -o $@




  8. 这个规则用于从 .c 文件编译生成 .o 文件。$< 是源文件,$@ 是目标文件。-c 选项告诉 gcc 只进行编译,不进行链接。

使用说明

  • 运行预处理:可以使用 make 命令来执行预处理和编译,或使用类似 make file.i 的命令来仅进行预处理。
  • 运行编译:执行 make 将编译所有 .c 文件并生成 .o 文件,最后链接成可执行文件。

通过这种方式,你可以灵活地设置和使用预处理器,同时保留了编译和链接的完整控制。

网络搜索

复制

CMakefile怎样定义全局可见宏

在 CMake 中定义全局可见宏可以通过设置 CMake 的编译选项来实现,这样所有的源文件在编译时都会使用这些宏定义。你可以使用 add_definitions() 或 target_compile_definitions() 来定义全局宏。

方法 1: 使用 add_definitions()

add_definitions() 用于向编译器添加全局编译选项,包括宏定义。这些宏定义会应用到所有的目标。

cmake_minimum_required(VERSION 3.10)

project(MyProject)

# 定义全局宏

add_definitions(-DMY_GLOBAL_MACRO=1 -DANOTHER_MACRO)

# 添加源文件

add_executable(my_executable main.cpp another_source.cpp)

在这个例子中,-DMY_GLOBAL_MACRO=1 和 -DANOTHER_MACRO 是两个全局宏定义,它们会被应用到所有的编译目标中。

方法 2: 使用 target_compile_definitions()

如果你希望宏定义仅对特定的目标有效,或者希望宏定义能够分组管理,target_compile_definitions() 是一个更好的选择。

cmake_minimum_required(VERSION 3.10)

project(MyProject)

# 添加源文件

add_executable(my_executable main.cpp another_source.cpp)

# 为特定目标定义宏

target_compile_definitions(my_executable PRIVATE MY_GLOBAL_MACRO=1 ANOTHER_MACRO)

在这个例子中,MY_GLOBAL_MACRO=1 和 ANOTHER_MACRO 只会在 my_executable 目标的编译中可见。PRIVATE 关键字表示这些宏定义只在该目标的编译中有效,而 PUBLIC 和 INTERFACE 可以用于不同的上下文。

方法 3: 使用 CMAKE_CXX_FLAGS  CMAKE_C_FLAGS

你也可以直接设置 CMake 变量来定义编译器标志,这将影响所有的编译目标。

cmake_minimum_required(VERSION 3.10)

project(MyProject)

# 定义全局宏

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMY_GLOBAL_MACRO=1 -DANOTHER_MACRO")

# 添加源文件

add_executable(my_executable main.cpp another_source.cpp)

总结

  • add_definitions():适用于需要全局应用的宏定义,但不推荐用于更复杂的目标设置。
  • target_compile_definitions():适用于目标特定的宏定义,推荐用于现代 CMake 项目。
  • CMAKE_CXX_FLAGS:用于全局编译选项设置,但可能不如 target_compile_definitions() 灵活。

选择哪种方法取决于你的具体需求和项目结构。

这篇关于Makefile问答之02 预处理器与宏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1143557

相关文章

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

Git 的特点—— Git 学习笔记 02

文章目录 Git 简史Git 的特点直接记录快照,而非差异比较近乎所有操作都是本地执行保证完整性一般只添加数据 参考资料 Git 简史 众所周知,Linux 内核开源项目有着为数众多的参与者。这么多人在世界各地为 Linux 编写代码,那Linux 的代码是如何管理的呢?事实是在 2002 年以前,世界各地的开发者把源代码通过 diff 的方式发给 Linus,然后由 Linus

MySQL record 02 part

查看已建数据库的基本信息: show CREATE DATABASE mydb; 注意,是DATABASE 不是 DATABASEs, 命令成功执行后,回显的信息有: CREATE DATABASE mydb /*!40100 DEFAULT CHARACTER SET utf8mb3 / /!80016 DEFAULT ENCRYPTION=‘N’ / CREATE DATABASE myd

GPU 计算 CMPS224 2021 学习笔记 02

并行类型 (1)任务并行 (2)数据并行 CPU & GPU CPU和GPU拥有相互独立的内存空间,需要在两者之间相互传输数据。 (1)分配GPU内存 (2)将CPU上的数据复制到GPU上 (3)在GPU上对数据进行计算操作 (4)将计算结果从GPU复制到CPU上 (5)释放GPU内存 CUDA内存管理API (1)分配内存 cudaErro

Kernel 中MakeFile 使用if条件编译

有时需要通过if  else来选择编译哪个驱动,单纯的obj-$(CONFIG_)就不是很方便,下面提供两种参考案例: 案例一: 来源:drivers/char/tpm/Makefileifdef CONFIG_ACPItpm-y += tpm_eventlog.o tpm_acpi.oelseifdef CONFIG_TCG_IBMVTPMtpm-y += tpm_eventlog.o

滚雪球学MyBatis(02):环境搭建

环境搭建 前言 欢迎回到我们的MyBatis系列教程。在上一期中,我们详细介绍了MyBatis的基本概念、特点以及它与其他ORM框架的对比。通过这些内容,大家应该对MyBatis有了初步的了解。今天,我们将从理论走向实践,开始搭建MyBatis的开发环境。了解并掌握环境搭建是使用MyBatis的第一步,也是至关重要的一步。 环境搭建步骤 在开始之前,我们需要准备一些必要的工具和软件,包括J

SAP学习笔记 - 开发02 - BTP实操流程(账号注册,BTP控制台,BTP集成开发环境搭建)

上一章讲了 BAPI的概念,以及如何调用SAP里面的既存BAPI。 SAP学习笔记 - 开发01 - BAPI是什么?通过界面和ABAP代码来调用BAPI-CSDN博客 本章继续讲开发相关的内容,主要就是BTP的实际操作流程,比如账号注册,登录,BTP集成开发环境的搭建这方面。 目录 1,账号注册 2,BTP登录URL 3,如何在BTP上进行开发? 以下是详细内容。 1,账

浙大数据结构:02-线性结构4 Pop Sequence

这道题我们采用数组来模拟堆栈和队列。 简单说一下大致思路,我们用栈来存1234.....,队列来存输入的一组数据,栈与队列进行匹配,相同就pop 机翻 1、条件准备 stk是栈,que是队列。 tt指向的是栈中下标,front指向队头,rear指向队尾。 初始化栈顶为0,队头为0,队尾为-1 #include<iostream>using namespace std;#defi

Spring点滴五:Spring中的后置处理器BeanPostProcessor讲解

https://www.cnblogs.com/sishang/p/6576665.html BeanPostProcessor接口作用:      如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中。   package com.t

【SpringMVC学习05】SpringMVC中的异常处理器

SpringMVC在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。 异常处理思路 我们知道,系统中异常包括两类:预期异常和运行时异常(RuntimeException),前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。系统的dao、service、controller出现异常都通过throws E