I'm trying to build a loadable kernel module using multiple source files. According to section 3.3 of https://www.kernel.org/doc/Documentation/kbuild/makefiles.txt I've got to use obj-m for main object file and modulename-y for the rest of it.
Here's my mwe:
helpers.h
#ifndef __HELPERS_H__
#define __HELPERS_H__
void helper_print_init(void);
void helper_print_exit(void);
#endif // __HELPERS_H__
helpers.c
#include "helpers.h"
#include <linux/kernel.h>
void helper_print_init(void) {
printk("multi_file_ko_init_helper\n");
}
void helper_print_exit(void) {
printk("multi_file_ko_exit_helper\n");
}
multiFileKo.c
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
//#include "helpers.h"
static int __init multi_file_ko_init(void) {
printk("multi_file_ko_init\n");
// helper_print_init();
return 0;
}
static void __exit multi_file_ko_exit(void) {
printk("multi_file_ko_exit\n");
// helper_print_exit();
}
module_init(multi_file_ko_init);
module_exit(multi_file_ko_exit);
MODULE_LICENSE("MIT");
MODULE_AUTHOR("AUTHOR");
MODULE_DESCRIPTION("gpio");
MODULE_VERSION("0.0");
NOTE THAT multiFileKo.c does not even actually uses helpers for now. I tried to actually call those functions but for simplicity just commented things out from mwe.
Now if I compile it with kbuild like follows, using only main file, I get dmesg output as expected:
obj-m := multiFileKo.o
But when I try to compile it linked with helpers, even without actually using them as follows, dmesg remains silent even though insmod/rmmod seem to be working:
obj-m := multiFileKo.o
multiFileKo-y := helpers.o
Obviously if I uncomment everything in multiFileKo.c it does not work either. So the fact of linking additional object file seems to be breaking my module regardless of what that additional object file does.
Approach with multiFileKo-objs does not work for me either. I saw this earlier, but sure where this takes it's origin, since makefiles manual uses it only in context of host programs.
Info which lead to solution was provided by #Tsyvarev. Original info may be found in comments to first post.
obj-m := multiFileKo.o defines the name of module. It also uses multiFileKo.c as a source file by default. But this principle works for single-source-file modules only.
In case multiple source files are used to create a module, obj-m := multiFileKo.o shall define module name, but not the sources. ALL object files (referencing actual sources) then shall be listed in multiFileKo-objs := list. Source files are not allowed to have the same name which module have.
From my experiments and make utility manual I can also say that it seems that listing sources in multiFileKo-y := also works. Maybe -obj is still working due to compatibility, since make documents now advise to use -y list.
To sum up, correct approach would be:
obj-m := multiFileKo.o
multiFileKo-y := multiFileKo_main.o helpers.o
Source files:
multiFileKo_main.c // contains init and exit functions
helpers.c
Output would be stored in multiFileKo.ko
Related
TLDR: Running ProC from Oracle instant client 12.2 on CentOS 7.3 doesn't seem to be able to properly process even a trivial input file.
Minimal input file demonstrating the problem:
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL INCLUDE oci.h;
EXEC SQL END DECLARE SECTION;
The real files obviously include my own project's header, but ultimately they pull in oci.h, which is one of the instant client SDK headers and this seems to be where the build issues are coming from.
Invocation of ProC:
The following script demonstrates the problem (again, a cut-down version of the real situation):
#!/bin/sh
export ORACLE_HOME=/some/path/instantclient_12_2
export ORACLE_SID=SomeSID
export PATH=/various/paths:${ORACLE_HOME}:${ORACLE_HOME}/sdk:${ORACLE_HOME}/bin:/some/more/paths/like:usr/bin:
export LD_LIBRARY_PATH=${ORACLE_HOME}:${ORACLE_HOME}/lib32:${ORACLE_HOME}/lib
${ORACLE_HOME}/sdk/proc \
LTYPE=LONG \
PARSE=PARTIAL \
MODE=ORACLE \
CODE=ANSI_C \
iname=foo.pc
Oracle configuration:
The contents of my pcscfg.cfg file look like this:
sys_include=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include
sys_include=/usr/include
include=/some/path/instantclient_12_2/sdk/include
I've also tried various reordering, switching include and sys_include, but all seem to give the same behaviour. Adding define=__x86_64__ as seen in various online references makes no difference. I've chosen to expand out the $ORACLE_PATH in the above to make the example clearer.
Sample error output:
Using the input file defined above results in output with errors like the following (truncated to help focus the discussion):
Pro*C/C++: Release 12.2.0.1.0 - Production on Mon Sep 4 16:19:45 2017
Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved.
System default option values taken from: /some/path/instantclient_12_2/precomp/admin/pcscfg.cfg
Syntax error at line 46, column 1, file /usr/include/bits/byteswap-16.h:
Error at line 46, column 1 in file /usr/include/bits/byteswap-16.h
{
1
PCC-S-02201, Encountered the symbol "{" when expecting one of the following:
; , = ( [
The contents around the line it is complaining about look like this:
static __inline unsigned short int
__bswap_16 (unsigned short int __bsx)
{ // <---- this is line 46
return __bswap_constant_16 (__bsx);
}
If I insert #include <stdlib.h> before the EXEC SQL BEGIN DECLARE SECTION line, the error message changes to this:
Syntax error at line 265, column 50, file /some/path/instantclient_12_2/sdk/include/ociextp.h:
Error at line 265, column 50 in file /some/path/instantclient_12_2/sdk/include/ociextp.h
void *ociepacm(OCIExtProcContext *with_context, size_t amount);
.................................................1
PCC-S-02201, Encountered the symbol "size_t" when expecting one of the following
:
... auto, char, const, double, enum, float, int, long,
ulong_varchar, OCIBFileLocator OCIBlobLocator,
OCIClobLocator, OCIDateTime, OCIExtProcContext, OCIInterval,
OCIRowid, OCIDate, OCINumber, OCIRaw, OCIString, register,
short, signed, sql_context, sql_cursor, static, struct,
union, unsigned, utext, uvarchar, varchar, void, volatile,
a typedef name, exec oracle, exec oracle begin, exec,
exec sql, exec sql begin, exec sql type, exec sql var,
The symbol "enum," was substituted for "size_t" to continue.
This one is more interesting because I've traced through the logic more carefully and even forcing size_t to be defined by various means, I still get the above error. But if I change the ProC invocation to use PARSE=FULL, it is successful. Unfortunately, that causes other problems with the real code and those problems have a similar nature to this one (i.e. chokes on compiler headers for things that should really have been defined by the compiler headers).
Further comments:
Looking at various solutions online, these issues are normally the result of having incorrectly set include search paths, but I've verified from the output listing that the correct headers are indeed being found. It is as though there are some compiler defines missing that GCC would normally provide but ProC isn't providing. There have been various other related examples which support this theory, giving errors on things like __INT_LEAST8_TYPE__ being unknown (which as far as I can tell GCC defines internally rather than explicitly in any of its headers).
Specific question:
ProC doesn't seem to be processing the system compiler headers correctly. Any idea why or even further things to try to help diagnose the underlying cause?
I have been able to get my application to compile correctly, I found that even though some compile problems were resolved by adding the output of the command "gcc -dM -E - < /dev/null" into a header file and including it in every Pro*C source file, new compile problems were introduced because of that and trying to resolve those new problems again introduced others so that approach was going nowhere.
In the end I started again from scratch and only included those #defines that were realy needed by the proc compiler. Also, I had to re-arrange the paths in the proc configuration file ${ORACLE_HOME}/precomp/admin/pcscfg.cfg
This is what it looks like now:
sys_include=$ORACLE_HOME/precomp/public
sys_include=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include
sys_include=/usr/local/include
sys_include=/usr/include
sys_include=/usr/include/linux
ltype=short
define=__x86_64__
the reason for this is that there are several files located in the gcc include directory that are also present in some of the other directories, but those assume that all of those gcc internal defines are set as well. The system include files located in the gcc include directory sometimes differ significantly from the ones in the usual include directories that are listed below it and it would seem that proc has a lot less difficulties in parsing the ones located in the gcc 4.8.5 directory.
Next to this, the include file I created and #include into every source file proc choked on now looks this:
#ifndef __GCC4_INTERNAL_DEFINES_H__
#define __GCC4_INTERNAL_DEFINES_H__
/* Proceed only when using the Oracle Pro*C compiler on RHEL7 */
#ifdef DB_PRE_COMP
#ifdef OS_IS_RHEL7
/* These are some of the defines that gcc4 sets by itself. The Pro*C precompiler
does not know them and they are needed in order to correctly parse several
system header files. Full list of gcc4 internal defines may be obtained with
the following command: gcc -dM -E - < /dev/null */
#define __INT_LEAST8_TYPE__ signed char
#define __INT_LEAST16_TYPE__ short int
#define __INT_LEAST32_TYPE__ int
#define __INT_LEAST64_TYPE__ long int
#define __UINT_LEAST8_TYPE__ unsigned char
#define __UINT_LEAST16_TYPE__ short unsigned int
#define __UINT_LEAST32_TYPE__ unsigned int
#define __UINT_LEAST64_TYPE__ long unsigned int
#define __INT_FAST8_TYPE__ signed char
#define __INT_FAST16_TYPE__ long int
#define __INT_FAST32_TYPE__ long int
#define __INT_FAST64_TYPE__ long int
#define __UINT_FAST8_TYPE__ unsigned char
#define __UINT_FAST16_TYPE__ long unsigned int
#define __UINT_FAST32_TYPE__ long unsigned int
#define __UINT_FAST64_TYPE__ long unsigned int
#define __INTMAX_TYPE__ long int
#define __UINTMAX_TYPE__ long unsigned int
#include </usr/include/stdint.h>
#endif /* OS_IS_RHEL7 */
#endif /* DB_PRE_COMP */
#endif /* __GCC4_INTERNAL_DEFINES_H__ */
Much to my relief, I got everything to compile again with these updates. For completeness sake, proc is executed with the parse=full option, this is what I used to do under RHEL6 as well and what my application apparently needs; as part of my efforts to get it to compile I tried with partial option as well but that did not make a difference, it still choked.
This happens when you include your header with the same name as a system header, which includes stdint.h.
From Pro*C manual:
The precompiler searches directories in the following order:
the current directory
the system directory specified in a SYS_INCLUDE precompiler option
the directories specified by the INCLUDE option, in the order they are entered
the built-in directories for standard header files
For example, you may create header file db.h for your project.
If you have in your system Berkeley DB installed, then it supplies your system with it's own db.h.
As long as your db.h is situated in the same folder as preprocessed .pc file and you don't have to pass include=your_include_folder option to proc you will be ok.
If you do have separate folder for include files you are obliged to pass include=../include option to proc and Berkeley's db.h comes in place instead of db.h file from your project.
For me, I fixed this in either of these 2 ways:
Add define=ORASYS_TYPES to ${ORACLE_HOME}/precomp/admin/pcscfg.cfg
or
Add DEFINE=ORASYS_TYPES as an option to proc.
oci.h includes <oratypes.h>
And oratypes.h has:
#ifndef ORASYS_TYPES
# include <sys/types.h>
# define ORASYS_TYPES
#endif
I have a library project that I'm working on porting to using the autotools suite in Linux. I'm quite new to autotools (this week). I've learned the basics of its operation. I have a question about how to keep the contents of config.h from being redefined.
I'm surprised to find that the generated config.h file doesn't either, 1) wrap each macro in a #ifndef or, 2) that the entire file isn't wrapped in the standard #ifndef CONFIG_H.
As I've alluded, this code is built on Windows and Linux. Thus there are several uses of a macro, _linux (I'm not saying that's the best name, but it's in use everywhere) to bring in elements to classes which exist in Linux only. Thus, this will happen
header.h
#ifndef HEADER1_H
#define HEADER1_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif
source.cxx
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "header.h" // oops, preprocessor gets excited because of redefs
One simple solution is I do that standard unique wrap in config.h.in after the file is generated. However, I was wondering, is there a better way of handling this? I can't be the first to encounter this and there might even be a means of handling it in configure.ac but being a complete neophyte in this, I don't know what to even search for.
The way I do this is indeed creating a wrapper file (which I usually call global.h) that reads like this.
#ifndef MY_PROJECT_GLOBAL_H
#define MY_PROJECT_GLOBAL_H
#include <config.h>
/* Maybe other global definitions… */
#endif
Note that the recommended way to #include the config.h file is via <config.h> not "config.h" so it works better with VPATH builds.
Then, all the source files in my project #include this global.h header as their very first #include and don't care about config.h. A header file should never #include config.h since this would lead to bad name conflicts. Actually, if you stick to this guideline, your code should also work without #include guards in the configuration header.
Update regarding OP's comment
Or: How to use configuration results in headers?
If your headers need to declare different things depending on the results of the configure script, you have a number of options, none of which is perfect.
For internal headers, there is no problem. They simply rely on the macros being #defined without #includeing anything. This works if – as is recommended – all source files #include (maybe indirectly as shown above) config.h before any other header.
If the headers are to be installed publicly, this is not such a great solution. For those of your users that use Autoconf, it wouldn't be that bad, although even those would have to remember what checks to place in their configure.ac files. For users who don't use Autoconf, it will be pretty bad. If you only have a few switches (such as Glibc's fature test macros), it is okay to ask your users to #define them before #includeing your headers but if you need many, this is not a real option. Not to mention that you'll expose a lot of implementation details to your users that way.
If all you need to do is branch depending on the platform you are building for, you could probe some of the pre-defined macros like __linux or _WIN32. There is the Boost.Predef library that aims to make these check a little more convenient by providing a higher-level abstraction. The library works with C and C++ alike but, of course, it adds an additional dependency to your project.
Finally, you could make a version of your config.h that uses a macro prefix specific to your project. There is a contribution in the Autoconf macro archive that does exactly that for you. A minimal example could look like this.
AC_PREREQ([2.69])
AC_INIT([example-project], [1.0], [bugs#example.org])
AC_CONFIG_SRCDIR([example.c])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AX_PREFIX_CONFIG_H([public_config.h], [EXAMPLE_PROJECT], [config.h])
AC_PROG_CC
AC_OUTPUT
Save this as configure.ac, download ax_prefix_config_h.m4 from the Autoconf macro archive and place it in the sub-directory m4 and then run autoreconf && ./configure. It will create the normal config.h and in addition public_config.h where in the latter file, all macros are prefixed with EXAMPLE_PROJECT_. The file public_config.h (which also has #include guards by the way) can be installed and #included in your project's public header files if need be.
With autoheader, you can add header and trailer boiler plate code to config.h
https://www.gnu.org/software/autoconf/manual/autoconf-2.60/html_node/Autoheader-Macros.html
For example, add the following to your configure.ac
#
# Add include guards to config.h
#
AH_TOP([
#ifndef __CONFIG_H_INCLUDE_GUARD
#define __CONFIG_H_INCLUDE_GUARD
])
AH_BOTTOM([
#endif
])
Assuming I have these two files:
Header.h
class DLL ExportClass{
public:
ExportClass();
static int test;
};
Source.cpp
#ifdef EXPORT
#define DLL __declspec(dllexport)
#else
#define DLL __declspec(dllimport)
#endif
#include "Header.h"
int ExportClass::test = 0;
ExportClass::ExportClass(){
}
And I won't define EXPORT (to import a already exported class with a static member), why do I get these warnings:
1>source.cpp(11): warning C4273: 'test' : inconsistent dll linkage
1> header.h(4) : see previous definition of 'public: static int ExportClass::test'
1>source.cpp(13): warning C4273: 'ExportClass::ExportClass' : inconsistent dll linkage
1> header.h(3) : see previous definition of '{ctor}'
And this error:
1>source.cpp(11): error C2491: 'ExportClass::test' : definition of dllimport static data member not allowed
If I define EXPORT it works. I kind of understand the warnings, but I thought, that the static variable and the ctor could be ignored by the compiler, because the whole class is declared as __declspec(dllimport) anyway. I want to use the same codebase for the __declspec(dllexport) and __declspec(dllimport) - but it seems the compiler stll tries to define these symbols that are marked as __declspec(dllexport) in their declaration. What is the common practice to solve this problem?
You are expecting the compiler to ignore a very serious mishap. It encountered the __declspec(dllimport) attribute on the class declaration, that quite unequivocally states that the class implementation is present in different module that's going to bound at runtime. But then it encountered the definition as well, completely unexpected since the attribute contract says that it is compiled in an entirely different project.
The C4273 warning is generated to remind you that it is very unclear what function is actually going to execute at runtime. There are two, one that is busy compiling, another in the DLL. Which one will actually execute is a wild guess. C4273 is a level 1 warning, the kind that fit the "this is almost surely wrong" category. It is not entirely impossible to work okay since there's some expectation that the functions have at least the same code. The odds that will not cause trouble are however not great, it could only work if the function doesn't have any side effects that change the internal DLL state. Very hard to diagnose bug when it does btw.
Then it encountered the exported variable. Same case, there are two of them. This is where the compiler programmer put his foot down, having code randomly use one or the other is no longer something that can be ignored. That just cannot ever work, the variables cannot have the same value. So C2491 is a hard error.
No idea how you got in this pickle, clearly the road you're trying to travel will make you fall off a steep cliff.
The only way I can reproduce your problem is to do the following:
Create a Win32 DLL project, call it Project1
Add the source code as you described
Compile the DLL and LIB
Change the project properties to remove EXPORT from the preprocessor definitions
Attempt to compile again (then I see your errors/warnings)
If, instead of steps 4 and 5, I do the following, I do not see an error:
Create a Win32 console application, call it Project2
Add source code as follows:
#include "Project1.h"
#pragma comment(lib, "Project1.lib")
int _tmain(int argc, _TCHAR* argv[])
{
ExportClass pClass;
return 0;
}
I suspect you see those errors because you are doing everything from the same DLL project and it is overwriting the LIB that it previously created and then attempting to import it.
If I am correct in guessing what you did, can you try using your DLL/LIB from another project and see what happens?
Although it is an old thread, it will be probably read by others. Therefore, if you want to make this code cross-compilable, I would usually define a header "export.h" like:
export.h
#pragram once
#if ! defined(DLL_API)
# if defined(_WIN32) // for windows builds
# if defined(myDLL_EXPORTS)
# define DLL_API __declspec(dllexport)
# else
# define DLL_API __declspec(dllimport)
# endif
# else // for linux builds
# define DLL_API
# endif
#endif
and include it in all the classes (.h) you want to export from your dll. You will also have to define the variable myDLL_EXPORTS as a parameter of the compiler for the dll project.
The way it works is very simple, when you are compiling your dynamic library (dll/so), because the variable myDLL_EXPORTS is defined, the compiler will replace DLL_API with __declspec(dllexport) so that your class can be consumed by the user of your dll. Conversely, when you are including the header file where you want to use your class at, because the variable myDLL_EXPORTS is not defined in the consumer project (it is defined only in the DLL project), the compiler will replace myDLL_EXPORT with __declspec(dllimport), so it knows that your class symbols are defined somewhere else (in this case, defined in your dll/so).
Finally, as __declspec(...) is a Windows-only thing, for linux we replace DLL_API with nothing.
I try to include R-code in C++ (Qt creator). To get familiar with the packages Rcpp, RInside and the R-source code R-3.0.1 I try to run the following example:
#include <QCoreApplication>
#include<iostream>
#include<Rcpp.h>
#include <RInside.h> // for the embedded R via RInside
int main(int argc, char *argv[]) {
RInside R(argc, argv); // create an embedded R instance
R["txt"] = "Hello, world!\n"; // assign a char* (string) to 'txt'
R.parseEvalQ("cat(txt)"); // eval the init string, ignoring any returns
exit(0);
}
First Question:
The file string.h comes from the package Rcpp, but it always generates a lots (130!) errors like:
'internal does not name a type'
'StringProxy does not name a type etc.
What is wrong with it?
Second Question:
In the .pro file I have to include all subfolder of the packages separatly like:
INCLUDEPATH += "W:\hesm\Private\Private\Qt files\ConnectToR\Rcpp\include\Rcpp\module"
Is it possible to include a folder (package) with all its subfolders in one quote?
Thanks
You are doing it wrong. The code you quote is verbatim from the examples/standards/rinside_sample0.cpp file of the RInside package.
It so happens that there is also a complete Qt example in examples/qt/ directory (albeit building a Qt application rather than a command-line one). You are expected to do
qmake && make
and the binary is built --- because all the required logic is in the .pro file.
Your question really is about how to use Qt Creator / Qt build tools, and has nothing to do with Rcpp or RInside per se.
Our supplied examples all work as documented and expected. Build them, look at what make executes and infer what you need for your use with Qt Creator (which is a fine tool, but not one supported by R out of the box). If you want to use it, you need to adapt to it locally.
I have a project that includes some performance sensitive native C++ headers making heavy use of templates. For this project we also wrap the headers and add some glue code to expose the functionality to c# and other .NET languages. We'll call this header "layout.h", and we'll assume it's a third party header that I can't change.
In a mixed mode C++/CLI assembly it is relatively easy to make a mistake and #include from a place in the code where #pragma unmanaged (or #pramga managed(push,off) ) . When that happens the templates generate IL, and I get extra managed/unmanaged transitions when running the code and performance goes down the drain.
My question is whether there is a way I can do a compile-time check just before the #include so that compilation fails if I am accidently #including from the wrong context.
// File1.cpp, compiled in a mixed mode C++/CLI assembly with /clr
ASSERT_UNMANAGED()
#include <layout.h>
My naive 1st attempt checked #ifdef _MANAGED, but that is always defined whether I'm in a #pragma unmanaged block of code or not.
The pragma directives must be inserted directly in the include file. In this way, everywhere you include the file an unmanaged section is declared.
Sorry that you have to modify your include file.
You may write ASSERT_MANAGED or ASSERT_UNMANAGED code that would use construct that is available ONLY while compiling managed or unmanaged. A ref class declaration is an example which is avaiable only when using managed.
This is somewhat a dirty solution, but it would work.
Here's a possible solution, making use of the fact that intrinsics are always compiled as native (unmanaged) code:
#include <intrin.h>
#define ASSERT_UNMANAGED() \
int TestFunc(void) { \
__pragma(warning(push)) \
__pragma(warning(error:4793)) \
auto aumt = [] () { return _bextr_u64(65537, 0, 8); }; \
__pragma(warning(pop)) \
return int(aumt()); }
#pragma unmanaged // Comment out this line and the assertion fails!
ASSERT_UNMANAGED()
#pragma managed
EDIT: Of course, if you just want warnings rather than compilation failure, you can remove the 3 __pragma(warning()) lines.