linux ubuntu下编译运行c程序,[Linux]在ubuntu系统下编译运行c程序并使用makefile管理项目...

先来看一下编译运行c程序的基本 命令。 虽然 刚装好的系统中已经有GCC了,但是这个GCC什么文件都不能编译, 因为 缺少 一些必须的头文件,所以要安装build-essential这个软件包。 输入命令: sudoapt-getinstallbuild-essential 其中 : sudo 是linux系统上

先来看一下编译运行c程序的基本命令。

虽然刚装好的系统中已经有GCC了,但是这个GCC什么文件都不能编译,

因为缺少一些必须的头文件,所以要安装build-essential这个软件包。

输入命令:sudo apt-get install build-essential

其中:

sudo 是linux系统上“以超级用户身份运行”的意思,允许系统管理员让普通用户执行一些root命令。

apt是一种包管理工具,后面的 install是告诉我想用apt安装某一个软件包 。

build-essential是c语言的开发包,包含了gcc make gdb和libc函数库。

安装完成后写一个 C 语言程序 hello.c 测试一下:

#include

int main()

{

printf("Hello Ubuntu!\n");

return 0;

}

在终端输入命令编译程序:

gcc hello.c -o hello

注意,如果不写-o hello,默认会生成a.out文件,选项 -o 用来指定所生成的可执行程序的文件名。

建议在后面加上-o hello来重命名生成文件的名称。

运行生成的文件的命令如下:

./hello

显示 Hello Ubuntu!

这样,C 语言编译器就算是安装成功了。

如果使用Eclipse for C++遇到问题binary not found,是因为没有编译成功,

使用ctrl+B或者点击菜单栏的build all即可。

如果出现gmake未定义 的问题,su切换到root权限之后,在终端输入一下命令即可:

ln -s /usr/bin/make /usr/bin/gmake

接下来是关于Makefile的内容。

MakeFile可以简单的理解为是一个项目管理的工具。

make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。

首先,用一个示例来说明Makefile的书写规则。

这个示例来源于GNU的make使用手册,在这个示例中,工程有8个C文件,和3个头文件,

我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。

规则是:

1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。

2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。

3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

只要我们的Makefile写得够好,所有的这一切,我们只用一个make命令就可以完成,

make命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,

从而自己编译所需要的文件和链接目标程序。

Makefile的规则很简单:

target ... : prerequisites ...

command

...

...

其中,

target也就是一个目标文件,可以是Object File,也可以是执行文件。

prerequisites就是,要生成那个target所需要的文件或是目标。

command也就是make需要执行的命令。(任意的Shell命令)

这是一个文件的依赖关系。

也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。

换句话说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。

这就是Makefile的规则。也就是Makefile中最核心的内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您的问题是如何在Ubuntu 22.04.2 LTS系统使用C语言编内核模块文件chardev.c和Makefile文件,实现简单的字符设备驱动程序,然后编测试程序test.c,访问创建的字符设备文件,并使用gcc编译这个字符设备文件然后运行。下面是一个简单的实现过程和步骤: 1. 创建chardev.c文件并编内核模块代码 ```c #include <linux/module.h> #include <linux/fs.h> // 定义file_operations等 #include <linux/uaccess.h> // copy_to_user等 #define DEVICE_NAME "chardev" // 设备名称 static int major_num; // 主设备号 static int device_open_count = 0; // 设备打开计数器 // 设备打开函数 static int device_open(struct inode *inode, struct file *file) { device_open_count++; printk(KERN_ALERT "Device has been opened %d time(s)\n", device_open_count); return 0; } // 设备关闭函数 static int device_release(struct inode *inode, struct file *file) { printk(KERN_ALERT "Device has been closed\n"); return 0; } // 设备读函数 static ssize_t device_read(struct file *file, char __user * buffer, size_t length, loff_t * offset) { char *msg = "Hello, this is chardev!\n"; int bytes_read = 0; while (length && *msg) { put_user(*(msg++), buffer++); length--; bytes_read++; } return bytes_read; } // 设备函数 static ssize_t device_write(struct file *file, const char __user * buffer, size_t length, loff_t *offset) { printk(KERN_ALERT "Sorry, this operation isn't supported yet.\n"); return -EINVAL; } // 设备I/O控制函数 static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { printk(KERN_ALERT "Sorry, this operation isn't supported yet.\n"); return -EINVAL; } // file_operations结构体,定义了设备的基本操作函数 static struct file_operations fops = { .read = device_read, .write = device_write, .unlocked_ioctl = device_ioctl, .open = device_open, .release = device_release, }; // 加载模块函数 static int __init chardev_init(void) { major_num = register_chrdev(0, DEVICE_NAME, &fops); if (major_num < 0) { printk(KERN_ALERT "Failed to register a major number\n"); return major_num; } printk(KERN_INFO "Chardev has been registered with major number %d\n", major_num); return 0; } // 卸载模块函数 static void __exit chardev_exit(void) { unregister_chrdev(major_num, DEVICE_NAME); printk(KERN_INFO "Chardev has been unregistered.\n"); } module_init(chardev_init); module_exit(chardev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("A simple character device driver"); ``` 2. 创建Makefile文件并编编译规则 ```Makefile obj-m += chardev.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean ``` 3. 编译内核模块 在终端中进入chardev.c和Makefile所在的目录,使用以下命令编译内核模块: ```bash make ``` 如果没有错误,会生成chardev.ko文件。 4. 编测试程序test.c ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #define DEVICE_NAME "/dev/chardev" // 设备文件路径 #define BUF_SIZE 256 // 读缓冲区大小 int main() { int fd; char buf[BUF_SIZE]; fd = open(DEVICE_NAME, O_RDWR); // 打开设备文件 if (fd < 0) { printf("Failed to open the device file\n"); return -1; } // 读取设备文件中的内容 if (read(fd, buf, BUF_SIZE) < 0) { printf("Failed to read from the device file\n"); return -1; } printf("%s", buf); // 打印读取的内容 close(fd); // 关闭设备文件 return 0; } ``` 5. 编译测试程序 在终端中进入test.c所在的目录,使用以下命令编译测试程序: ```bash gcc -o test test.c ``` 6. 运行测试程序 在终端中进入test.c所在的目录,使用以下命令运行测试程序: ```bash ./test ``` 如果一切正常,应该能够在终端中看到设备文件中的内容被打印出来了。 注意:在运行测试程序之前,需要确保已经加载了chardev模块,可以使用以下命令加载模块: ```bash sudo insmod chardev.ko ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值