相对于使用libc构建的新Linux标头进行构建 [英] Build against newer linux headers than libc is built using
问题描述
我想使用新的 SCHED_DEADLINE
自Linux 3.14 起可用的调度策略.>
我从一个简单的程序开始尝试使用sched_setattr
函数.
#include <sched.h>
int main(void)
{
// struct sched_attr attr;
// attr.size = sizeof(struct sched_attr);
// attr.sched_policy = SCHED_DEADLINE;
sched_setattr(0, (void*)0, 0);
return 0;
}
但是,编译时出现以下错误:
$gcc dead.c
dead.c: In function ‘main’:
dead.c:8:2: warning: implicit declaration of function ‘sched_setattr’ [-Wimplicit-function-declaration]
sched_setattr(0, (void*)0, 0);
^~~~~~~~~~~~~
/tmp/ccGxWxZE.o: In function `main':
dead.c:(.text+0x19): undefined reference to `sched_setattr'
collect2: error: ld returned 1 exit status
我的系统正在运行Ubuntu 16.10 Yakkety,其内核为4.8.0-59-generic.包含的sched.h
文件可在/usr/include/sched.h
中找到,并由软件包libc6-dev
提供.该头文件不包含函数sched_setattr
和我要使用的朋友.
但是,我安装的内核(和内核头文件)带有一个sched.h
头文件,其中包含我需要的定义.它位于我系统上的/usr/src/linux-headers-4.8.0-58/include/linux/sched.h
.
因此,我天真地认为让我们仅根据较新的linux头文件而不是libc6-dev提供的头文件进行构建.我的程序只能在此或更新的内核上运行,但这很好.
我将第一行修改为:#include <linux/sched.h>
并执行:
gcc -I/usr/src/linux-headers-$(uname -r)/include -I/usr/src/linux-headers-$(unam -r)/arch/x86/include dead.c
现在我得到的是错误和警告的页面.这似乎不是要走的路.
针对比libc提供的Linux头更新的Linux头构建用户空间程序的正确方法是什么?
然后我该如何在上面构建程序?
sched_setattr()
是一个系统调用,似乎没有一对一的libc包装器.您可以自己进行包装,如下所示:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <linux/sched.h>
#include <sys/syscall.h>
#include <sys/types.h>
struct sched_attr {
uint32_t size; /* Size of this structure */
uint32_t sched_policy; /* Policy (SCHED_*) */
uint64_t sched_flags; /* Flags */
int32_t sched_nice; /* Nice value (SCHED_OTHER, SCHED_BATCH) */
uint32_t sched_priority; /* Static priority (SCHED_FIFO, SCHED_RR) */
/* Remaining fields are for SCHED_DEADLINE */
uint64_t sched_runtime;
uint64_t sched_deadline;
uint64_t sched_period;
};
static int sched_setattr (pid_t pid, const struct sched_attr *attr, unsigned int flags)
{
return syscall (SYS_sched_setattr, pid, attr, flags);
}
int main (int argc, char *argv[])
{
struct sched_attr attr;
int res;
memset (&attr, 0, sizeof (struct sched_attr));
attr.size = sizeof (struct sched_attr);
res = sched_setattr (getpid (), &attr, 0);
if (res < 0) {
perror ("sched_setattr");
return 1;
}
return 0;
}
在尝试包含获取struct sched_attr
定义所需的内核头文件并阅读谷歌搜索用户空间中的内核头"时发现的注释时,我发现确实不建议尝试包含内核头文件就是为此.
I want to write a program using the new SCHED_DEADLINE
scheduling policy available since Linux 3.14.
I start out with a simple program trying to use the sched_setattr
function.
#include <sched.h>
int main(void)
{
// struct sched_attr attr;
// attr.size = sizeof(struct sched_attr);
// attr.sched_policy = SCHED_DEADLINE;
sched_setattr(0, (void*)0, 0);
return 0;
}
However when compiling I get the following error:
$gcc dead.c
dead.c: In function ‘main’:
dead.c:8:2: warning: implicit declaration of function ‘sched_setattr’ [-Wimplicit-function-declaration]
sched_setattr(0, (void*)0, 0);
^~~~~~~~~~~~~
/tmp/ccGxWxZE.o: In function `main':
dead.c:(.text+0x19): undefined reference to `sched_setattr'
collect2: error: ld returned 1 exit status
My system is running Ubuntu 16.10 Yakkety, with kernel 4.8.0-59-generic. The sched.h
file included is found in /usr/include/sched.h
and is provided by the package libc6-dev
. This headerfile does not contain the function sched_setattr
and friends that I am trying to use.
However the kernel (and kernel headers) I have installed comes with a sched.h
header file containing the definitions I need. It is located at /usr/src/linux-headers-4.8.0-58/include/linux/sched.h
, on my system.
So I naively think lets just build against the newer linux headers instead of the libc6-dev provided headers. My program will only run on this or newer kernels, but that is just fine.
I modify the first line to be: #include <linux/sched.h>
and execute:
gcc -I/usr/src/linux-headers-$(uname -r)/include -I/usr/src/linux-headers-$(unam -r)/arch/x86/include dead.c
Now I am getting page after page of errors and warning. This does not seem the way to go.
What is the correct way to build a userspace program against a newer Linux headers than those that are provided by libc?
And subsequently how do I build the program above?
sched_setattr()
is a syscall and doesn't seem to have one-to-one libc wrapper. You could do the wrapper yourself, something like this:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <linux/sched.h>
#include <sys/syscall.h>
#include <sys/types.h>
struct sched_attr {
uint32_t size; /* Size of this structure */
uint32_t sched_policy; /* Policy (SCHED_*) */
uint64_t sched_flags; /* Flags */
int32_t sched_nice; /* Nice value (SCHED_OTHER, SCHED_BATCH) */
uint32_t sched_priority; /* Static priority (SCHED_FIFO, SCHED_RR) */
/* Remaining fields are for SCHED_DEADLINE */
uint64_t sched_runtime;
uint64_t sched_deadline;
uint64_t sched_period;
};
static int sched_setattr (pid_t pid, const struct sched_attr *attr, unsigned int flags)
{
return syscall (SYS_sched_setattr, pid, attr, flags);
}
int main (int argc, char *argv[])
{
struct sched_attr attr;
int res;
memset (&attr, 0, sizeof (struct sched_attr));
attr.size = sizeof (struct sched_attr);
res = sched_setattr (getpid (), &attr, 0);
if (res < 0) {
perror ("sched_setattr");
return 1;
}
return 0;
}
Looking at the errors reported when trying to include kernel header files required to get the definition of struct sched_attr
and reading the comments found by Googling "kernel headers in user space", I really can't suggest trying to include kernel header files just for this.
这篇关于相对于使用libc构建的新Linux标头进行构建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!