Build against newer linux headers than libc is built using

五迷三道 提交于 2019-12-12 03:39:24

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/45692699/build-against-newer-linux-headers-than-libc-is-built-using

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!