Changing block of code based on CONFIG entries in Linux Kernel - linux

I had a question about using the CONFIG entries of the .config file used in the Linux kernel. I would like to skip through some part of the code in a function in a file based on whether a certain CONFIG entry is y or not. What is the best way of doing that? I am wondering if an 'if statement' can be used in any way. One workaround which I tried was maintaining two copies of almost the same file, renaming, and changing the makefile entries based on CONFIG, but this method involves quite some code duplication. Was wondering if there is a smarted way of doing this.

You can use an #ifdef on the CONFIG variable - it's recommended that you put the #ifdef in the .h file, then you could use that to change a flag for your function to reference.
See: http://www.linuxjournal.com/article/6568

Related

AC_CHECK_HEADERS: define a macro before testing for header presence

A particular C++ logging library called spdlog that I use in my project has a broken package on CentOS (the platform I'm trying to compile on) where the header file will only compile if SPDLOG_FMT_EXTERNAL is defined before any of its files are included. [And this will not be fixed.]
I am trying to find a way to use autoconf directives to test for the presence of this header file - previously I used a homegrown macro that compiles a program which uses that, but its speed latency is unacceptably slow so I am trying to replace it.
Here is the relevant snippet of my configure.ac:
dnl check for libfmt is done earlier...
AC_CHECK_HEADERS([spdlog/spdlog.h], [have_spdlog="yes"], [have_spdlog="no"])
if test x$have_spdlog = xyes; then
LDFLAGS="$LDFLAGS -lspdlog -lfmt";
else
AC_MSG_ERROR([spdlog is required for logging support but is missing.])
fi
The header file spdlog/spdlog.h exists, but Autoconf deems it as not usable because it won't compile by itself.
AC_CHECK_HEADERS has a parameter I can specify include files required to include that particular header file. I can use that to specify the #define macro before the file is included.
Is there an easier way to just directly specify a macro without creating a new header file?
After some experimenting, I learned that the fourth parameter to AC_CHECK_HEADERS accepts macros as well - anything that can be used in a C/C++ preprocessor works as well, such as #ifdef, #endif and so on. It is not restricted to only #include directives.
AC_CHECK_HEADERS([spdlog/spdlog.h], [have_spdlog="yes"], [have_spdlog="no"], [
#define SPDLOG_FMT_EXTERNAL
])

Include once capability in Inno Setup Preprocessor?

I am creating a library of script methods and only want to include them when needed in my installers.
Some of the methods need to use other methods so I was putting the #include "filename.iss" for the needed methods in the file with the method that needs it.
However, if I include two files in an installer script file that also include a common file I get a "Duplicate identifier" error in the second file that includes it.
I've searched for something like #include-once but can't find any results for it.
To reproduce you can just include the same file twice:
#include "AddReplaceLinesInFile.iss"
#include "AddReplaceLinesInFile.iss"
The only way I can see to avoid this is to not put the includes in the files with the methods that need them and just add them in the main installer script.
I'm leaving the includes in the top of the method files that need them but commenting them out - for documentation purposes and to make it easy to copy and paste them into my main installer script. However I'd prefer to use something like an include-once capability.
Does Inno Setup have anything like include-once or a way to test for an already defined method so I could create something similar?
TIA
Use the same trick as is used in C/C++, the include guard:
In the C and C++ programming languages, an #include guard, sometimes called a macro guard, is a particular construct used to avoid the problem of double inclusion when dealing with the include directive.
Surround the code in the included file with #ifndef UniqueName, #define UniqueName ... #endif:
#ifndef IncludeIss
#define IncludeIss
procedure Test;
begin
end;
#endif
The UniqueName is typically the same as filename, with punctuation removed (to make it a valid identifier). I.e. for include.iss the name can be IncludeIss.
See Inno Setup Preprocessor: #ifdef, #ifndef, #ifexist, #ifnexist.
There is no such thing as include-once.
Inno Setup is Pascal based where functions (and procedures) are global! There are no private ones.
Preprocessor Symbols are scoped to the .iss file and to make them global use public keyword.
Variables have really unpleasant behavior: if you define global variable (in [Code] section) with the same name as local variable you never know into which variable the value is really assigned.
Compiler does not check this which is really bad.

Finding the default project settings file

I'm trying to write a plugin for 3ds max, I went through the entire sdk installation process to the letter as described in the help files.
The problem I'm facing though is intellisence complaining about an invalid macro definition
"IntelliSense: command-line error: invalid macro definition:_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT =1"
I found the definition in project settigs -> c/c++ -> preprocessor definitions as inherited from parent or project default.
I tried disabling the inherited definitions and re-entered them, this time without the space between the name and the = and all works fine so I'm guessing its a typo on their part?
Anyway, I want to change the default project or whatever to not repeat it every time i start a new project. The project is created with a wizard which required me to copy over some files to appear and after which I had to enter the sdk path.
The files I copied are plain text with some fancy extensions and not much in them so I'm guessing the defaults are described in the sdk directory.. somewhere. Does anybody know what kind of a file I'm looking for?
EDIT: I found a file called root.vcxproj_template and it has a section for preprocessor definitions but all it contains is
<PreprocessorDefinitions>_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
and no mention of the broken one
EDIT2: in another part of the file there was a path to a property sheet (maxsdk\ProjectSettings\propertySheets\3dsmax.common.tools.settings) which included the faulty definition. I fixed it an no more complaints from VS.
_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT = 1 means that compiler should replace all old C run-time routines such as sprintf, strcpy, strtok with new versions such as strprintf_s, strcpy_s, strtok_s and similar. It goes in pair with following definition _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES = 1.
More you can find here: (MSDN) https://msdn.microsoft.com/en-us/library/ms175759.aspx. However I tried to use this but without success. It says that you can use this only for statically allocated buffers like char buffer[32], but compilers was still complaining bout unsecure strcpy.

Is there a way to tell whether code is now being compiled as part of a PCH?

I need to branch a certain statement in a precompiled-header .h file, based on whether the .h is now being used to create the PCH (i.e., included in a cpp compiled with /Yc), or now included just to use the PCH (i.e., included in a cpp compiled with /Yu).
In other words, I'm looking for something like -
#ifdef NOW_CREATING_THE_PCH
#import yadayada_with_option_a
#else
#import yadayada_with_option_b
#endif
...and can't find anything.
Any ideas would be appreciated!
Thanks,
-Ofek
[Edit:] The reason I need this is that I use Incredibuild, and have started getting this warning. Per the FAQ suggestion, I wish to #import with no_implementation during PCH creation, and with implementation_only during PCH usage.
You can specifically change the configuration (in Visual Studio) of stdafx.cpp (or whatever source file you have that gets compiled with /Yc) to define the symbol NOW_CREATING_THE_PCH, leaving the symbol undefined for the rest of the source files (which get compiled with /Yu).
That's not something you get out-of-the-box, but if you need to do it just for one project (or a few), it's not a problem.
While this is not a direct answer to your question, the simplest way of solving this problem is to use the #import statement with no_implementation in the header file which is used to generate the precompiled header (usually StdAfx.h) and re-#import the header file into the source file that is used to trigger the generation of the pch with the parameter implementation_only. That way the implementation of the wrapper functions are being defined, but only in one place.

On GNU/Linux systems, Where should I load application data from?

In this instance I'm using c with autoconf, but the question applies elsewhere.
I have a glade xml file that is needed at runtime, and I have to tell the application where it is. I'm using autoconf to define a variable in my code that points to the "specified prefix directory"/app-name/glade. But that only begins to work once the application is installed. What if I want to run the program before that point? Is there a standard way to determine what paths should be checked for application data?
Thanks
Thanks for the responses. To clarify, I don't need to know where the app data is installed (eg by searching in /usr,usr/local,etc etc), the configure script does that. The problem was more determining whether the app has been installed yet. I guess I'll just check in install location first, and if not then in "./src/foo.glade".
I dont think there's any standard way on how to locate such data.
I'd personally do it in a way that i'd have a list of paths and i'd locate if i can find the file from anyone of those and the list should containt the DATADIR+APPNAME defined from autoconf and CURRENTDIRECTORY+POSSIBLE_PREFIX where prefix might be some folder from your build root.
But in any case, dont forget to use those defines from autoconf for your data files, those make your software easier to package (like deb/rpm)
There is no prescription how this should be done in general, but Debian packagers usually installs the application data somewhere in /usr/share, /usr/lib, et cetera. They may also patch the software to make it read from appropriate locations. You can see the Debian policy for more information.
I can however say a few words how I do it. First, I don't expect to find the file in a single directory; I first create a list of directories that I iterate through in my wrapper around fopen(). This is the order in which I believe the file reading should be done:
current directory (obviously)
~/.program-name
$(datadir)/program-name
$(datadir) is a variable you can use in Makefile.am. Example:
AM_CPPFLAGS = $(ASSERT_FLAGS) $(DEBUG_FLAGS) $(SDLGFX_FLAGS) $(OPENGL_FLAGS) -DDESTDIRS=\"$(prefix):$(datadir)/:$(datadir)/program-name/\"
This of course depends on your output from configure and how your configure.ac looks like.
So, just make a wrapper that will iterate through the locations and get the data from those dirs. Something like a PATH variable, except you implement the iteration.
After writing this post, I noticed I need to clean up our implementation in this project, but it can serve as a nice start. Take a look at our Makefile.am for using $(datadir) and our util.cpp and util.h for a simple wrapper (yatc_fopen()). We also have yatc_find_file() in case some third-party library is doing the fopen()ing, such as SDL_image or libxml2.
If the program is installed globally:
/usr/share/app-name/glade.xml
If you want the program to work without being installed (i.e. just extract a tarball), put it in the program's directory.
I don't think there is a standard way of placing files. I build it into the program, and I don't limit it to one location.
It depends on how much customising of the config file is going to be required.
I start by constructing a list of default directories and work through them until I find an instance of glade.xml and stop looking, or not find it and exit with an error. Good candidates for the default list are /etc, /usr/share/app-name, /usr/local/etc.
If the file is designed to be customizable, before I look through the default directories, I have a list of user files and paths and work through them. If it doesn't find one of the user versions, then I look in the list of default directories. Good candidates for the user config files are ~/.glade.xml or ~/.app-name/glade.xml or ~/.app-name/.glade.xml.

Resources