Trouble with hello world linux kernel module makefile - linux

I have this code for the hello world module :
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void)
{
printk(KERN_INFO "Hello module\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Bye module\n");
}
Makefile :
obj-m := hello.o
K := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(K) M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
I get this compile message from the makefile :
make -C /lib/modules/3.16.0-4-amd64/build M=/home/neo/ker modules
make[1]: Entering directory '/usr/src/linux-headers-3.16.0-4-amd64'
Makefile:10: *** mixed implicit and normal rules: deprecated syntax
make[1]: Entering directory `/usr/src/linux-headers-3.16.0-4-amd64'
CC [M] /home/neo/ker/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/neo/ker/hello.mod.o
LD [M] /home/neo/ker/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-3.16.0-4-amd64'
this is the warning that i don't understand:
Makefile:10: *** mixed implicit and normal rules: deprecated syntax
Thanks in advance

Related

link error with "undefined lua_xxxxx" when building lsnes

In my ubuntu 14.xx, I try to compile lsnes emulator to use the mario-ai script from aleju/mario-ai, and I've tried to google many solutions to solve the problem below:
Here is the output from the console:
make[3]: __all__.files' is up to date.
make[3]: Leaving directory/home/pengsuyu/software/lsnes/sourcecode/src/platform/macosx'
make[2]: Leaving directory /home/pengsuyu/software/lsnes/sourcecode/src/platform'
g++ -o lsnescat all_common.files all_platform.files-pthread -lboost_iostreams -lboost_filesystem -lboost_system -lz -lgcrypt -lgpg-error -L/usr/lib/x86_64-linux-gnu -lcurl -rdynamic -ldlcat core/all.ldflags lua/all.ldflags fonts/all.ldflags library/all.ldflags interface/all.ldflags video/all.ldflags emulation/all.ldflags cmdhelp/all.ldflags platform/all.ldflags
core/multitrack.o: In functionlua::state::get_string(int, std::string const&)':
/home/pengsuyu/software/lsnes/sourcecode/src/core/../../include/library/lua-base.hpp:317: undefined reference to lua_tolstring'
core/multitrack.o: In functionlua::state::get_bool(int, std::string const&)':
/home/pengsuyu/software/lsnes/sourcecode/src/core/../../include/library/lua-base.hpp:334: undefined reference to lua_toboolean'
core/multitrack.o: In functionlua::state::type(int)':
.
.
/home/pengsuyu/software/lsnes/sourcecode/src/library/lua.cpp:536: undefined reference to lua_close'
library/lua.o: In functionlua::state::pushcfunction(int ()(lua_State))':
/home/pengsuyu/software/lsnes/sourcecode/src/library/../../include/library/lua-base.hpp:504: undefined reference to lua_pushcclosure'
library/lua.o: In functionlua::state::getfield(int, char const*)':
/home/pengsuyu/software/lsnes/sourcecode/src/library/../../include/library/lua-base.hpp:506: undefined reference to lua_getfield'
library/lua.o: In functionlua::state::insert(int)':
/home/pengsuyu/software/lsnes/sourcecode/src/library/../../include/library/lua-base.hpp:509: undefined reference to lua_insert'
collect2: error: ld returned 1 exit status
make[1]: *** [lsnes] Error 1
make[1]: Leaving directory/home/pengsuyu/software/lsnes/sourcecode/src'
make: *** [src/all_files] Error 2
==================================
At the beginning, I think, the linker cannot find my lua library. So I tried to compile my main.cpp with test.lua.
main.cpp:
#include <stdio.h>
#include <iostream>
//extern "C"
//{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
//} // liblua5.1-c++.a
lua_State * L;
int main ()
{
L = lua_open();
luaL_openlibs(L);
luaL_dofile(L, "d:\\test.lua");
return 0;
}
test.lua:
print("Hello World");
I write a MakeFile to generate the executable file "main":
main:main.o
gcc -o $# $< -llua5.1 -lstdc++
main.o:
gcc -c main.cpp
clean:
-rm *.o
It works when I add the compile option "-llua5.1" and "-lstdc++" otherwise it throws the same error as I compiled lsnes
I am not familiar with gcc and Makefile. Please help me to solve this problem.
I've solved my question
The way to solve this problem is just to change one line in the file named "options.build".
1. find the line "LUA=lua" in options.build
2. change this line to "LUA=lua5.1"
because the needed library is 5.1, so if you want to build it successfully, you must use the "lua5.1" library however the default configuration is "lua" not "lua5.1"

LKM Makefile, extract source files from source directories

I have the following project structure for a simple kernel module and I want to be able to build this by extracting the source files from the provided source directories in the Makefile.
Makefile
src/
main.c
sub_src/
sub_src.c
sub_src.h
I will describe my issue soon but I will first provide the code.
main.c :
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include "sub_src/sub_src.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Unknown");
MODULE_DESCRIPTION("A Simple Hello World module");
static int __init hello_init(void)
{
printk(KERN_INFO "Hello world!\n");
sub_src_printk("sub_src.c\n");
return 0;
}
static void __exit hello_cleanup(void)
{
printk(KERN_INFO "Cleaning up module.\n");
}
module_init(hello_init);
module_exit(hello_cleanup);
sub_src.h :
#ifndef __SUB_SRC_H___
#define __SUB_SRC_H___
#include <linux/kernel.h> // included for KERN_INFO
void sub_src_printk( const char* );
#endif /* __SUB_SRC_H___ */
sub_src.c :
#include "sub_src.h"
void sub_src_printk( const char* msg )
{
printk(KERN_INFO "%s", msg);
}
Makefile :
MODULE_NAME ?= test_module
TEST ?= 0
INCLUDE_DIRS = -I$(src)/src/sub_src
ccflags-y := $(INCLUDE_DIRS)
ifeq ($(TEST), 1)
SRC_DIRS := \
src \
src/sub_src
SRCS := $(foreach src_dir,$(SRC_DIRS),$(wildcard $(src_dir)/*.c))
else
SRCS := \
src/main.c \
src/sub_src/sub_src.c
endif
#extract required object files
OBJ_SRCS := $(SRCS:.c=.o)
#setup kbuild
obj-m += $(MODULE_NAME).o
$(MODULE_NAME)-y := $(OBJ_SRCS)
$(MAKE) = make
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
all:
#echo ""
#echo "------- Building the LKM ($(MODULE_NAME).ko) -------"
#echo "INCLUDE_DIRS = $(INCLUDE_DIRS)"
#echo "SRCS = $(SRCS)"
#echo "OBJS_SRCS = $(OBJ_SRCS)"
#echo "ccflags-y = $(ccflags-y)"
#echo "obj-m = $(obj-m)"
#echo "test_module-y = $(test_module-y)"
#echo "-----------------------------------------------------"
#echo ""
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
The idea is that I should be able to build this module by providing only the source directories in the Makefile by calling make as:
make all TEST=1
But I have the option (for now) to provide the path to the source files by calling make as following:
make all TEST=0
These two calls should ideally provide the same result i.e a functional kernel module ready to be inserted (via sudo insmod ...). This is however not the case. (make all TEST=0 works as intended while make all TEST=1 does not)
make all TEST=0 gives the following output: (make clean has been called before this command)
------- Building the LKM (test_module.ko) -------
INCLUDE_DIRS = -I/src/sub_src
SRCS = src/main.c src/sub_src/sub_src.c
OBJS_SRCS = src/main.o src/sub_src/sub_src.o
ccflags-y = -I/src/sub_src
obj-m = test_module.o
test_module-y = src/main.o src/sub_src/sub_src.o
-----------------------------------------------------
make -C /lib/modules/3.19.0-59-generic/build M=/home/henrik/Desktop/test_lkm_dev/new_test modules
make[1]: Entering directory `/usr/src/linux-headers-3.19.0-59-generic'
CC [M] /home/henrik/Desktop/test_lkm_dev/new_test/src/main.o
CC [M] /home/henrik/Desktop/test_lkm_dev/new_test/src/sub_src/sub_src.o
LD [M] /home/henrik/Desktop/test_lkm_dev/new_test/test_module.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/henrik/Desktop/test_lkm_dev/new_test/test_module.mod.o
LD [M] /home/henrik/Desktop/test_lkm_dev/new_test/test_module.ko
make[1]: Leaving directory `/usr/src/linux-headers-3.19.0-59-generic'
make all TEST=1 gives the following output: (make clean has been called before this command)
------- Building the LKM (test_module.ko) -------
INCLUDE_DIRS = -I/src/sub_src
SRCS = src/main.c src/sub_src/sub_src.c
OBJS_SRCS = src/main.o src/sub_src/sub_src.o
ccflags-y = -I/src/sub_src
obj-m = test_module.o
test_module-y = src/main.o src/sub_src/sub_src.o
-----------------------------------------------------
make -C /lib/modules/3.19.0-59-generic/build M=/home/henrik/Desktop/test_lkm_dev/new_test modules
make[1]: Entering directory `/usr/src/linux-headers-3.19.0-59-generic'
make[2]: *** No rule to make target `/home/henrik/Desktop/test_lkm_dev/new_test/test_module.c', needed by `/home/henrik/Desktop/test_lkm_dev/new_test/test_module.o'. Stop.
make[1]: *** [_module_/home/henrik/Desktop/test_lkm_dev/new_test] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.19.0-59-generic'
make: *** [all] Error 2
The debugging info shows (as far I can see) that the variables in the Makefile contains the same values with the different approaches.
But the second alternative (TEST=1) somehow have the impression that there should be a source file called test_module.c which isn't the case.
Do someone/anyone have an idea why this happens and how I can solve it? (I have been pulling my hair out for the last two hours..)
Solution (The Makefile):
MODULE_NAME ?= test_module
TEST ?= 0
INCLUDE_DIRS = -I$(src)/src/sub_src
ccflags-y := $(INCLUDE_DIRS)
ifeq ($(TEST), 1)
# Paths to source directories
SRC_DIRS := \
src \
src/sub_src
SRCS := $(foreach src_dir,$(SRC_DIRS),$(wildcard $(src)/$(src_dir)/*.c))
SRCS := $(SRCS:$(src)/%=%)
else
SRCS := \
src/main.c \
src/sub_src/sub_src.c
endif
# extract required object files
OBJ_SRCS := $(SRCS:.c=.o)
# setup kbuild
obj-m := $(MODULE_NAME).o
$(MODULE_NAME)-y := $(OBJ_SRCS)
$(MAKE) = make
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
all:
#echo ""
#echo "------- Building the LKM ($(MODULE_NAME).ko) -------"
ifeq ($(TEST), 1)
#echo "Compiling with TEST = 1"
else
#echo "Compiling with TEST = 0"
endif
#echo ""
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
Many thanks!
Henrik

Module verification failed when insmod a module

On Ubuntu 14.04, Kernel 3.13.0, When I insert below simple module, I got error message from kernel log:
"module verification failed: signature and/or required key missing - tainting kernel"
Did I made any mistake or missed anything?
Here is module source code in a file named ts2.c.
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_ALIAS("hello2");
static int __init hello1_init(void)
{
printk(KERN_INFO "Hello world 2.\n");
return 0;
}
static void __exit hello1_exit(void)
{
printk(KERN_INFO "Goodbye world 2.\n");
}
module_init(hello1_init);
module_exit(hello1_exit);
Here is the Makefile:
ifeq ($(DEBUG),y)
DEBFLAGS = -O -g -DPCI_INFO_DEBUG # "-O" is needed to expand inlines
else
DEBFLAGS = -O2
endif
EXTRA_CFLAGS += $(DEBFLAGS) -I$(LDDINC)
ifneq ($(KERNELRELEASE),)
obj-m := ts2.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD) clean
endif
depend .depend dep:
$(CC) $(EXTRA_CFLAGS) -M *.c > .depend
ifeq (.depend,$(wildcard .depend))
include .depend
endif
You have a problem in your make file...
ifeq ($(DEBUG),y)
DEBFLAGS = -O -g -DPCI_INFO_DEBUG # "-O" is needed to expand inlines
else
DEBFLAGS = -O2
endif
EXTRA_CFLAGS += $(DEBFLAGS) -I$(LDDINC)
ifneq ($(KERNELRELEASE),)
obj-m := ts2.o
Rather it should be as below:
ifeq ($(DEBUG),y)
DEBFLAGS = -O -g -DPCI_INFO_DEBUG # "-O" is needed to expand inlines
else
DEBFLAGS = -O2
endif
EXTRA_CFLAGS += $(DEBFLAGS) -I$(LDDINC)
ifneq ($(KERNELRELEASE),)
obj-m := hello1.o
Now your issues should be solved

Linking cuda object file

I have one .cu file that contains my cuda kernel, and a wrapper function that calls the kernel. I have a bunch of .c files as well, one of which contains the main function. One of these .c files calls the wrapper function from the .cu to invoke the kernel.
I compile these files as follows:
LIBS=-lcuda -lcudart
LIBDIR=-L/usr/local/cuda/lib64
CFLAGS = -g -c -Wall -Iinclude -Ioflib
NVCCFLAGS =-g -c -Iinclude -Ioflib
CFLAGSEXE =-g -O2 -Wall -Iinclude -Ioflib
CC=gcc
NVCC=nvcc
objects := $(patsubst oflib/%.c,oflib/%.o,$(wildcard oflib/*.c))
table-hash-gpu.o: table-hash.cu table-hash.h
$(NVCC) $(NVCCFLAGS) table-hash.cu -o table-hash-gpu.o
main: main.c $(objects) table-hash-gpu.o
$(CC) $(CFLAGSEXE) $(objects) table-hash-gpu.o -o udatapath udatapath.c $(LIBS) $(LIBDIR)
So far everything is fine. table-hash-gpu.cu calls a function from one of the .c files. When linking for main, I get the error that the function is not present. Can someone please tell me what is going on?
nvcc compiles both device and host code using the host C++ compiler, which implies name mangling. If you need to call a function compiled with a C compiler in C++, you must tell the C++ compiler that it uses C calling conventions. I presume that the errors you are seeing are analogous to this:
$ cat cfunc.c
float adder(float a, float b, float c)
{
return a + 2.f*b + 3.f*c;
}
$ cat cumain.cu
#include <cstdio>
float adder(float, float, float);
int main(void)
{
float result = adder(1.f, 2.f, 3.f);
printf("%f\n", result);
return 0;
}
$ gcc -m32 -c cfunc.c
$ nvcc -o app cumain.cu cfunc.o
Undefined symbols:
"adder(float, float, float)", referenced from:
_main in tmpxft_0000b928_00000000-13_cumain.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Here we have code compiled with nvcc (so the host C++ compiler) trying to call a C function and getting a link error, because the C++ code expects a mangled name for adder in the supplied object file. If the main is changed like this:
$ cat cumain.cu
#include <cstdio>
extern "C" float adder(float, float, float);
int main(void)
{
float result = adder(1.f, 2.f, 3.f);
printf("%f\n", result);
return 0;
}
$ nvcc -o app cumain.cu cfunc.o
$ ./app
14.000000
It works. Using extern "C" to qualify the declaration of the function to the C++ compiler, it will not use C++ mangling and linkage rules when referencing adder and the resulting code links correctly.

Why I'm not getting "Multiple definition" error from the g++?

I tried to link my executable program with 2 static libraries using g++. The 2 static libraries have the same function name. I'm expecting a "multiple definition" linking error from the linker, but I did not received. Can anyone help to explain why is this so?
staticLibA.h
#ifndef _STATIC_LIBA_HEADER
#define _STATIC_LIBA_HEADER
int hello(void);
#endif
staticLibA.cpp
#include "staticLibA.h"
int hello(void)
{
printf("\nI'm in staticLibA\n");
return 0;
}
output:
g++ -c -Wall -fPIC -m32 -o staticLibA.o staticLibA.cpp
ar -cvq ../libstaticLibA.a staticLibA.o
a - staticLibA.o
staticLibB.h
#ifndef _STATIC_LIBB_HEADER
#define _STATIC_LIBB_HEADER
int hello(void);
#endif
staticLibB.cpp
#include "staticLibB.h"
int hello(void)
{
printf("\nI'm in staticLibB\n");
return 0;
}
output:
g++ -c -Wall -fPIC -m32 -o staticLibB.o staticLibB.cpp
ar -cvq ../libstaticLibB.a staticLibB.o
a - staticLibB.o
main.cpp
extern int hello(void);
int main(void)
{
hello();
return 0;
}
output:
g++ -c -o main.o main.cpp
g++ -o multipleLibsTest main.o -L. -lstaticLibA -lstaticLibB -lstaticLibC -ldl -lpthread -lrt
The linker does not look at staticLibB, because by the time staticLibA is linked, there are no unfulfilled dependencies.
That's an easy one. An object is only pulled out of a library if the symbol referenced hasn't already been defined. Only one of the hellos are pulled (from A). You'd get errors if you linked with the .o files.
When the linker tries to link main.o into multipleLibsTest and sees that hello() is unresolved, it starts searching the libraries in the order given on the command line. It will find the definition of hello() in staticLibA and will terminate the search.
It will not look in staticLibB or staticLibC at all.
If staticLibB.o contained another symbol not in staticLibA and that was pulled into the final executable, you then get a multiple definition of hello error, as individual .o files are pulled out of the library and two of them would have hello(). Reversing the order of staticLibA and staticLibB on the link command line would then make that error go away.

Resources