I want to develop some small linux kernel modules in CLion. For example, I want to compile these files:
stack.h:
#ifndef _LL_STACK_H
#define _LL_STACK_H
#include <linux/list.h>
typedef struct stack_entry {
struct list_head lh;
void *data;
} stack_entry_t;
stack_entry_t* create_stack_entry(void *data);
void delete_stack_entry(stack_entry_t *entry);
void stack_push(struct list_head *stack, stack_entry_t *entry);
stack_entry_t* stack_pop(struct list_head *stack);
#define stack_empty(stack) list_empty((stack))
#define STACK_DATA(stack_entry, data_ptr_type) \
((data_ptr_type)(stack_entry)->data)
#define STACK_DATA_RESET(stack_entry, new_data) \
do { \
(stack_entry)->data = new_data; \
} while(0)
#endif //_LL_STACK_H
main.c:
#include <stdio.h>
#include "stack.h"
int main() {
printf("hello");
return 0;
}
Is it possible to configure CMakeLists.txt to complete my task? I try to add some directories (linux, include, kernel), but I have no success.
Yes, It is. But you will need to write make file for building kernel module.
Update 1:
I recommend QtCreator for writing linux kernel module.
See my manual
Update 2:
I also recommend eclipse cdt.
See eclipse manual about how to prepare it for linux kernel.
The approach I use to spelunk the linux kernel via clion is:
create a compile_commands.json for the kernel using an intercepted build
use a ruby script to convert compile_commands.json into an clion friendly CMakeLists.txt
This allows for both code navigation and also a reasonable editing experience.
See for more details https://github.com/habemus-papadum/kernel-grok
If you are only talking about proper auto-suggestions but are fine with invoking "make" by yourself then check this demo setup: https://gitlab.com/phip1611/cmake-kernel-module
It's a simplified version of https://gitlab.com/christophacham/cmake-kernel-module/-/blob/master/CMakeLists.txt (I forked it).
I use it for both: out-of-tree kernel module development (standalone development) as well as in-tree development.
Always make sure to have latest kernel header files installed!
$ sudo apt install kernel-headers-$(uname -r)
Related
so.. there is code. explain the code line by line. and i have the message that 'features.h' file not found and 'libioP.h' file not found. how i can fix it? compiler minGW in QT
#include <features.h>
#undef __GLIBC_USE_DEPRECATED_SCANF
#define __GLIBC_USE_DEPRECATED_SCANF 1
#include <stdarg.h>
#include <stdio.h>
#include <libioP.h>
/* Read formatted input from stdin according to the format string FORMAT. */
/* VARARGS1 */
int
__scanf (const char *format, ...)
{
va_list arg;
int done;
va_start (arg, format);
done = __vfscanf_internal (stdin, format, arg, 0);
va_end (arg);
return done;
}
ldbl_strong_alias (__scanf, scanf)
You might need to install libraries to support GCC. The solution varies depending on what OS you use.
If you are using Ubuntu, use:
sudo apt install build-essential
For other OS, you can search install build-essential + your OS for further information
Build-essential s a collection of essential libraries for the compiler, the .h files you posted belong to one of these libraries. Did you check the packages when install the MinGW? It should be in Basic Setup like this
Those libraries which name includes gcc or lib are very likely needed in your current and future projects, you can reinstall the MinGW to download these packages.
I am developing firmware for stm32f4xx based systems.
For that I setup a toolchain based on the arm-none-eabi-gcc toolchain form ARM and cmake.
This toolchain works on Ubuntu. I can x-compile and debug(via openocd + eclipse IDE).
Now I like to add do some functional testing for my code. I was checking and it seems that cmocka is a good tool to use for embedded software testing.
I am now looking for an example/template that integrates a test into the cmake build.
let's assume a simple function at myfunc.c
#include "myFunc.h"
int buffer[10];
void myFunc(int i, int val) {
buffer[i] = val;
}
if I got it right I can do a test in a separate c file like "test.c"
#include "myFunc.h"
#include <cmocka.h>
// function success
static void test_myFunc_positive() {
for(int i = 0; i < 10; i++) {
myFunc(i,i);
}
}
static void test_myFunc_outofbounds() {
myFunc(100,44);
}
int main(void) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_myFunc_positive),
cmocka_unit_test(test_myFunc_outofbounds),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}
Usually I run
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE="cmake/STM32Toolchain.cmake"
My question contains some sub questions:
1.) I installed libcmocka-dev. This is for my host system. Do I need to install cmocka for my arm-none-eabi-gcc compiler?
2.) How to setup cmake to pick the cmocka lib, build the test and run it on the host system? Think my toolchain file needs to be ignored.
Your source code looks pretty fine. Here is a recipe of how you could use cmocka.
I recommend to crosscompile cmocka's source code, too. In fact I doing it in this way:
Add cmocka.c to your sources
Add 'cmocka.h and cmocka_pbc.h and cmocka_private.h to your include directories.
Compile and run your software
PS: I don't know libcmocka-dev. I think this is a precompiled version of cmocka?
PPS: I had some trouble on getting cmocka's output redirected to my serial UART. If you're having the same problems, feel free to ask.
I have a C linux API library that I distribute both to end users and to servers. When a user needs to use this library, they compile and build a .so file that they send to our servers to be run. I would like a way to compile in the version number of the library into their .so file such that my server can check what version they compiled on. This way if the server is incompatible with the user's .so file, I can refuse to load the library. I'm not sure what options I even have to achieve this and was hoping for any type of suggestion. Please let me know if any more information would be helpful in solving this issue.
It's common for libraries to have a getLibraryVersion function that returns some constant value, be it a string, integer, or whatever. This would get you the version you linked against (i.e. your .so version). You could have an additional macro to get the version you compiled against (i.e. your server's version).
For example, SDL's API has a version struct and the following function defined in one of its headers:
#define SDL_MAJOR_VERSION 1
#define SDL_MINOR_VERSION 2
#define SDL_PATCHLEVEL 15
typedef struct SDL_version {
Uint8 major;
Uint8 minor;
Uint8 patch;
} SDL_version;
/**
* This macro can be used to fill a version structure with the compile-time
* version of the SDL library.
*/
#define SDL_VERSION(X) \
{ \
(X)->major = SDL_MAJOR_VERSION; \
(X)->minor = SDL_MINOR_VERSION; \
(X)->patch = SDL_PATCHLEVEL; \
}
/**
* Use this function to get the version of SDL that is linked against
* your program.
*/
extern void SDL_GetVersion(SDL_version* ver);
In one of your .so's .c files:
void SDL_GetVersion(SDL_version* ver)
{
SDL_VERSION(ver);
}
Example use:
SDL_version compiled;
SDL_version linked;
SDL_VERSION(&compiled);
SDL_GetVersion(&linked);
printf("We compiled against SDL version %d.%d.%d ...\n",
compiled.major, compiled.minor, compiled.patch);
printf("We are linking against SDL version %d.%d.%d.\n",
linked.major, linked.minor, linked.patch);
On a side note; it's a little dangerous to be running somebody else's code on your servers.
Lua tutorials all over the net show the use of lua_register() to expose the functions implemented in your extension DLL or so:
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static int pushlua3(lua_State *L)
{
lua_pushnumber(L, 3);
return 1;
}
int luaopen_lua3pushbinder(lua_State *L)
{
lua_register(L,"pushlua3", pushlua3);
return 0;
}
lua_register() is a macro and not a function, this is from the 5.2 manual:
http://www.lua.org/manual/5.2/manual.html#lua_register
[-0, +0, e]
void lua_register (lua_State *L,
const char *name,
lua_CFunction f);
Sets the C function f as the new value of global name. It is defined
as a macro:
#define lua_register(L,n,f) \
(lua_pushcfunction(L, f), lua_setglobal(L, n))
if you use the functions separately, lua_pushcfunction is fine, but lua_setglobal crashes because it's trying to reference LUA_GLOBALSINDEX and that fails at runtime, not compile time.
So what is the right way to implement lua_register() now?
I would sort of have expected that when Lua moved to 5.2 and redid the concepts manifested with LUA_GLOBALSINDEX and thus lua_register() it would have been reasonable to change lua_register() so that it did it the 'new' way.
So, is there a header update that Ubuntu didn't pick up for lua5.2? should i have an include path that points to /usr/include/lua5.2 and then I wouldn't face this problem? I only have a Lua 5.1 include directory on my box.
tnx for any help you can provide.
The answer is that on Ubuntu 13.04 the Ubuntu Software Center informed me of the existence of lua5.2 but did not inform me of the existence of liblua5.2-0-dev.
I used apt-get to find it based on the suggestion for lhf that I needed the 5.2 headers.
My lua script calling a native dll/so demo went off just fine as a result
Hello how to rewrite probably bad construction?
I tryed to ask how to fix it to make it work there,but maybe it's all the bad conception.
Any other solution to do that?
It's compiled in Eclipse using GCC for linux, compiled as C code.
file first.h
#ifndef FIRST_H_
#define FIRST_H_
typedef struct foo
{
int a;
char *c;
} foo_struct;
#endif /* FIRST_H_ */
file second.h:
#ifndef SECOND_H_
#define SECOND_H_
#include "first.h"
typedef struct wtf
{
foo_struct *poleFOO[5];
}wtf_struct;
#endif /* SECOND_H_ */
Concretely in file second.h row foo_struct *poleFOO[5]; throws: "foo_struct could not be resolved"
I work on Linux Ubuntu 11.10 using gcc in editor Eclipse for C and C++.
Okay, this is not an error from the compiler but from Eclipse. Simply Googl'ing the error "could not be resolved" points me to articles talking about Eclipse CDT (the eclipse subsystem for C/C++ development).
So it has something to do with Eclipse, your C headers look syntactically right. I believe that without a C file but only headers, Eclipse does not know how to parse the headers only to create its own index database (must be used for intellisense, symbols list, etc.)
I suggest you insert a simple C file including second.h, and with a main() function so that the link step passes as well, for example:
#include "second.h"
int main() {
wtf_struct my_variable;
return 0;
}
I had the same Error: "vuint16 - could not be resolved" for a wrapped type within typedef (mentioned below) and it was successfully resolved by rebuilding the Index in Eclipse Environment(right click on project -> Index -> Rebuild)
Note: It is not a compiler error!
[headerfile1: can.h]
#define vuint8 uint8
[headerfile2: can_local.h]
#include "Can.h" /* include all needed types */
typedef struct sCanRxFullInfoStruct
{
vuint16 objectNumber; //error line
} tCanRxFullInfoStruct;
I suspect that you've created (and included) two headers that both have the same header guard
#ifndef FIRST_H_
#define FIRST_H_
I had the same problem after creating a set of typedefs that wrap other types.
The solution was to rebuild Eclipse Index - right click on project -> Index -> Rebuild
I landed here because I had a similar problem and Eclipse was also to blame (I reproduced using only GCC and it works). I tried to reproduce the OP's issue, but it compiled OK in my environment :/.
So I will show what worked for me instead.
The only thing that helped was to make the extern declaration using struct, and the actual definition in the source file using the new type I defined with typedef, like so:
lib1.h:
typedef struct sMyStruct
{
// struct fill
}tMyStruct;
lib2.h:
extern struct sMyStruct my_struct, *p_my_struct;
//extern tMyStruct my_struct, *p_my_struct; // This wouldn't work
lib2.c:
tMyStruct my_struct, *p_my_struct;
With extern tMyStruct in lib2.h it would not compile (the typedef was not recognized), no matter what. Cleaning the project wouldn't help, neither would rebuilding the index, etc.
Astonishingly, I tried to reproduce the problem minimally in a new project... and it compiles fine! With both versions! So, I don't know, Eclipse got hung up on some wicked ghost file or something.
I was stuck for days, the only thing that worked on the actual project was what I showed above.