I am studying the C language, and I saw a new extension that I had not seen before.
What do files with the extension like library.h.in mean?
Is it as the simple header with extension ".h"? What's the difference?
These files are usually the input for autoconf which will generate final .h files.
Here's an example from PCRE:
#define PCRE_MAJOR #PCRE_MAJOR#
#define PCRE_MINOR #PCRE_MINOR#
#define PCRE_PRERELEASE #PCRE_PRERELEASE#
#define PCRE_DATE #PCRE_DATE#
Autoconf will replace all variables (#…#) with the respective values and the result will be a .h file.
Typically, a .h.in file is a header template that is filled in to become the actual header by a configure script based on the outcome of several tests for features present on the target platform.
Files ending with .in are typically template files used by a program called configure that generates a new file without the extension after substituting for variable expansions. I.e., if you're looking at a source tree that has files called, e.g. Makefile.in in the tree, then ./configure will generate a usable Makefile that can be used to "make" from source.
Related
Background
I have a large cmake project that makes use of dozens of subprojects: some from in-house code bases, and some third-party projects which also use CMake.
To ensure common compiler options, I setup a macro in CMake called CreateDevFlags which is run in only the in-house sub-projects own CMakeLists file as the first line of code to execute. This makes sure that I don't break the compiler flags, output directory overrides, etc, for third-party projects, and all of the code I wrote myself is built with identical options.
Additionally, each sub project has a simple block of code along the lines of the following to define the source files to be compiled:
file(GLOB subproject_1A_SRC
"src/*.c"
)
file(GLOB subproject_1A_INC
"inc/*.h"
)
file(GLOB subproject_2B_SRC
"src/*.c"
"extra_src/*.c"
)
file(GLOB subproject_2B_INC
"inc/*.h"
"extra_details_inc/*.h"
)
Goal
I would like to add a sanity-check custom rule/function to the "master" CMakeLists file at the project root which runs all of the code for in-house subprojects through a code sanitizer (checks newlines, enforces style rules, etc).
Question
Is there a trivial way to have all "special" (ie: in-house) subprojects append their own source files to a "master" list of source (.c) and header (.h) files (possibly via the macro I created)? I realize I could manually create this list in the master CMakeLists file, but then I'd be duplicating efforts, and code maintainers would have to modify code in two places with this in effect.
Thank you.
One possible implementation would be to have a list called FILE_TRACKER defined at top scope for your project. Then, you could do something like
# Create local list to append to
set(LOCAL_LIST ${FILE_TRACKER})
# Append all of your source files, from your local source
foreach(SRC_FILE ${subproject_1A_SRC})
list(APPEND LOCAL_LIST ${SRC_FILE})
endforeach()
# Append to the upper macro (note: was initially set with FILE_TRACKER)
set(FILE_TRACKER ${LOCAL_LIST} PARENT_SCOPE)
The developers would only have to add their source to the one list, and the macro at the top level will be updated with the files.
In the end. the following approach solved my problem:
set(DIR1_SRCS "file1.cpp" PARENT_SCOPE)
and then in ./CMakeLists.txt
set(SRCS ${DIR1_SRCS} ${DIR2_SRCS})
I suggest you don't examine header files. Instead use include dirs for the paths to the header files. If you do this you will automatically get the depends working without having to track them yourself.
Your sanitizer should be able to parse the actual code to find and read the included headers.
I have three .asn files. After these three files are compiled by the asn.1 compiler, each file has a corresponding directory in the output folder. In each folder, there are many C source files that were generated by the asn.1 compiler. There is always a .c file which has the same name as the .asn file (except the extension name, i.e. test.asn and test.c). In this file, some functions are defined; like asn_alloc, asn_free etc.
So, there are three files implementing the asn_alloc and asn_free functions. I'll use all the generated C files in my C project.
The problem is, the asn_alloc function is defined in three places. This is the reason I'm getting the compiler error:
multiple definition of function
How do I deal with this problem? I think that editing the generated source file is not a good idea.
This problem is specific to the ASN.1 Tool you are using. With some ASN.1 Tools (such as the one at http://www.oss.com), you can either include all of the .asn files in the same compilation so that one .c file is generated with all names disambiguated, or you can use the -prefix xxx option on each compilation where xxx is different for each ASN.1 compilation thus causing the generated names to be prefixed with xxx, therefore not conflicting.
I have two sets of header files and .c files in my project i will only ever be including one of these headers but i want the option to quickly swap the header im including. Both header files have some declarations that are exactly the same but the implementations in the .c files are different. Basically what I need is way to tell the compiler to only compile the .c file that is associated with the header im including elsewhere in my program.
You could always specify the .c or .o file that you're going to link against at compile/link time for instance
gcc -o myexe file1.c/file1.o
or
gcc -o myexe file2.c/file2.o
you could even make this a different make directive if you have a makefile if you have the same header file but 2 different implementations. I would recommend just using 1 header file and changing the underlying implementation, no point in having 2 headers with similar declarations.
If both header files are exactly the same then you don't need to maintain two header files. You can keep only one copy. Whichever code includes the header file can include this single header file only.
You can always specify which .c file you want to compile while compiling. In gcc, you can mention the C file to be compiled in the command line. In Visual Studio, you can include the correct C file.
I guess you should maintain only one header file and include that in your code. Introduce a flag to the makefile to link which implementation to be linked. You have not mentioned what are you using to build.
I'm trying to use a non-standard header file (http://ndevilla.free.fr/gnuplot). Its used in lots of codes in various different places on my computer. Currently I have to put the header file and the object file in every folder which its needed with the preprocessor directive:
#include "gnuplot_i.h"
In the file. Is there a way by which I can put the header file in one place so I can reference it like other standard header file. Cheers.
Compile with -I<directory>
E.g.
compile with -I/usr/local/gnuplot/inc.
Also it might be worth your reading up on include paths and the difference between:
#include <include_file.h>
and
#include "include_file.h"
Linking in an object file needs to be done explicitly the same way as a C file, which means (I believe) that you need a full path. However if you archive it into a proper library then you can use -l<library name> and -L<library path> instead. E.g.
gcc -I/usr/local/gnuplot/inc -L/usr/local/gnuplot/lib -lgnuplot -o my_prog my_prog.c
Most compilers have a flag -I that lets you add a directory of your choosing to the search path for include files.
I have a set of C files that I would like to use. Can I just copy them to my include directory, or do I have to compile them. I would think they would be compiled in the final binary.
You need to compile those C files if you want to use them.
To make use of what's in those C files, you'll nead a header file that declares what's inside them.
Those header files is what you'd put in your include folder, and you'll compile the C files together with your other C files. (Or you could make a library out of those C files)
Yes, they need to be compiled so that they are available at the linking step. C is not an interpreted language, so having the sources present in an include directory would do nothing for execution.
You can keep the source files at the same location. The include files will be in the include directory. You can use the compilation option -I./<include-file-directory> to specify from where to fetch the include files.
The final binary will be compiled version of all your source files which you give to the compiler. You have to explicitly specify every file to be compiled along the with final executable name.
In case you dont do so a default executable is created with the name a.out(i am assuming the platform to be linux and compiler to be gcc) in the directory where you compile.
Check the link for more details on compilation using Makefile.