Disabling vim's location list on missing C header file - c

Vim is pretty smart when it comes to C, so if one inserts a bogus header file such as #include <stdioo.h>, it complains by bringing up a location list with the following error:
foo.c:1|20| fatal error: stdioo.h: No such file or directory
|| compilation terminated.
Which is great, but for whatever reason, I get the same error when including the <mpi.h> header file. I know this is a vim problem b/c I can compile and execute the program with mpicc and mpiexec, respectively. Besides it being extremely irritating having it pop up every time I save the file, all syntax errors are ignored when this happens.
Is there any way to instruct vim to ignore this header file, or at least all the header files?

WHERE on your filesystem is the <mpi.h> file located?
Often it's one level down, such as /usr/include/mpi/mpi.h and would require <mpi/mpi.h> to access it.
You may need to add another directory path to the -I option list of your compiler, or add the directory path to VIM's path option variable
:help 'path
Will get you started on the VIM side, you'll need to look up how to add options to your current setup, no idea if you're using cmake, make, visual something, netclipse or whatever.
But a simple 'locate mpi.h' would be the place to start, since you know it's there.
You said "pop-up" ... are you using syntastic or such? Again, finding the proper path would help there too. Evidently mpicc knows the proper path to the include files, you just need to tell VIM. (via the 'path' option)

Related

GCC cannot recognize the directory path inside a file

The problem I encountered in using GCC is that I cannot use the command make to build my program because some files contain the paths of their actual location.
Say I have a file named "machine.h", its content is target-pisa/pisa.h. At the same time, in the same working directory, I have a folder named "target-pisa", in which there is a file named "pisa.h"; the actual code of the header file "machine.h" is actually inside the file "pisa.h", which is inside the folder named "target-pisa" located in the same working directory as "machine.h".
Assume for some reason I cannot simply copy and paste the code from "pisa.h" to "machine.h"; that is, I have to stick with what is provided by the prof. The make command does not work in this case in my laptop because it cannot interpret target-pisa/pisa.h as a directory path and open the actual header file "pisa.h" according to the path target-pisa/pisa.h provided in the file "machine.h". Instead, git bash interprets target-pisa/pisa.h as C code (if I am not mistaken); see the figure below.
Some additional info that may be helpful:
In machine.h, there is only one line of code as shown below:
target-pisa/pisa.h
I have checked that almost all .c files in the working directory have #include "machine.h".
How can I solve this problem? Please help, I have been stuck in this for a long time. By the way, my friend also used git bash to do this lab and this problem doesn't happen to him.
I tried to reinstall git bash in order to see if the problem can be solved, but it didn't.
All in all, I want to build the program successfully by using make command in git bash.
machine.h needs to have an #include directive to tell the compiler to pull in the nested header.
#include "target-pisa/pisa.h"
Just writing target-pisa/pisa.h by itself isn't valid C code.

GNU gcc compiler cannot handle partial include statements

Imagine that I have a C-project in the following folder:
C:\microcontroller\stm32\myProject
I have two important folders inside myProject:
- source => here are all my .c and .h files
- build => gcc will write all the object files in here
Note: as you can see, the backward slashes indicate that this is happening on a Windows pc.
The figure below gives an overview:
I will not display my complete makefile here, because that would lead us too far. The rules inside the makefile for all .c => .o files are similar. Let us just focus on the compilation of one specific file: fileA2.c:
--------------------- COMPILATION OF FILE fileA2.c -------------------
Building ./build/folderA/fileA2.o
arm-none-eabi-gcc C:\\microcontroller\\stm32\\myProject\\source\\folderA\\fileA2.c
-o C:\\microcontroller\\stm32\\myProject\\build\\folderA\\fileA2.o
-c
-MMD
-mcpu=cortex-m7
-...
-IC:/microcontroller/stm32/myProject/source/folderA
-IC:/microcontroller/stm32/myProject/source/folderB
Notice that the gcc call ends with two include flags: one for folderA and one for folderB. This enables gcc to use any of the header files from these folders (fileA1.h, fileA2.h or fileB1.h) if fileA2.c has an import statement.
Let us now consider the source code in fileA2.c. We assume that this file needs to include fileA2.h and also fileB1.h.
/*******************************/
/* SOURCE CODE fileA2.c */
/*******************************/
// Some include statements
#include "fileA2.h"
#include "fileB1.h"
// Code
...
These include statements work perfectly. The gcc compiler retrieves the files fileA2.h and fileB1.h in the given folders. But I noticed that the following does not work:
/*******************************/
/* SOURCE CODE fileA2.c */
/*******************************/
// Some include statements
#include "fileA2.h"
#include "folderB/fileB1.h"
// Code
...
The last include statement is a 'partial path' to the file. I get the error when compiling:
fatal error: folderB/fileB1.h: No such file or directory
How can I get gcc to handle this?
PS: It is not my own habit to use 'partial paths'. But they appear a lot in the libraries from the silicon vendor of my chip, so I have to live with it.
You specify two paths to look for includes other than the current directory for the source file:
-IC:/microcontroller/stm32/myProject/source/folderA
-IC:/microcontroller/stm32/myProject/source/folderB
You get the error because neither
C:/microcontroller/stm32/myProject/source/folderA/folderB/fileB1.h nor
C:/microcontroller/stm32/myProject/source/folderB/folderB/fileB1.h exists.
To address the error, you can add the following path:
-IC:/microcontroller/stm32/myProject/source
When using double-quotes to include a header file the compiler first looks in the same directory as the current file. If the header file is not found then it continues with the standard include search paths.
So when the compiler compiles the file source/folderA/fileA2.c the first directory the compiler will look for include files is the source/folderA directory. In the first example the fileB1.h will not be found there, but since you added source/folderB to the standard search path it will be found there as source/folderB/fileB2.h.
In the second example there is no folderB/fileB1.h file on source/folderA so the compiler will search the standard search path. When it comes to source/folderB it will again try folderB/fileB2.h (i.e. source/folderB/folderB/fileB2.h) and it will still not be found, nor will it be found anywhere else.
You need to add -IC:/microcontroller/stm32/myProject/source to be able to find folderB/fileB1.h.
Apart of the two correct responses you have received before this, you have the third chance to specify the path to the file in the #include directive from the curren directory, as with
`#include "../folderB/fileB1.h"

How do I generate included files using cmake?

I've got a tool that generates files that contain definitions and declarations. These files need to be included from other source files or headers - they aren't usable standalone.
The obvious thing to do is have a custom command to generate them. My CMakeLists.txt that does this is as follows. I'm currently using this with the GNU makefile generator.
project(test_didl)
cmake_minimum_required(VERSION 3.0)
add_custom_command(
OUTPUT test_didl_structs.h test_didl_structs.c
COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/didl.py --decls=test_didl_structs.h --defs=test_didl_structs.c ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/didl.py ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py)
add_executable(test_didl test_didl.c)
target_include_directories(test_didl PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(test_didl shared_lib)
test_didl.c is very simple:
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "test_didl_structs.h"
#include "test_didl_structs.c"
int main(void) {
}
But on the first build, make tries to build test_didl.c, which of course fails, because test_didl_structs.* haven't been generated yet. Naturally, before the first successful build of test_didl.c, the dependency information isn't known, so make doesn't know to run the python command first.
I tried a custom target, but that's no good, because custom targets are assumed to be always dirty. This means the C file is recompiled on every build and the EXE is linked. This approach won't scale.
My eventual solution was to make the output .h file an input to the executable:
add_executable(test_didl test_didl.c test_didl_structs.h)
.h file inputs are treated as dependencies, but don't otherwise do anything interesting for makefile generators. (I am not currently interested in other generators.)
So that works, but it feels a bit ugly. It doesn't actually state explicitly that the custom commands need to be run first, though in practice this seems to happen. I'm not quite sure how, though (but I'm not up to speed on reading the CMake-generated Makefiles just yet).
Is this how it's supposed to work? Or is there something neater I'm supposed to be doing instead?
(What I'm imagining, I suppose, is something like a Visual Studio pre-build step, in that it's considered for running on every build, before the normal dependency checking. But I want this pre-build step to have dependency checking, so that it's skipped if its inputs are older than its outputs.)
My eventual solution was to make the output .h file an input to the executable.
This way is correct.
It actually states, that building executable depends on given file, and, if that file is OUTPUT for some add_custom_command(), this command will be executed before building executable.
Another way is to generate needed headers at configuration stage using execute_process(). In that case there is no need to add header files as sources for add_executable(): CMake has notion of autodetecting dependencies for compiling, so test_didl will be rebuilt after regeneration of test_didl_structs.h.
execute_process(COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/didl.py --decls=test_didl_structs.h --defs=test_didl_structs.c ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py)
# ...
add_executable(test_didl test_didl.c)
Drawback of this approach is that you need manually rerun configuration stage after changing your .py files. See also that question and answer to it.
Another problem is that header file will be updated every time configuration is run.
You can try tell cmake that you are using an external source, see docs about set_source_files_properties, see this past post

Converting an absolute path in #include in C

I am trying to get some code that I acquired from a repository to work on my system.
In one of the C files, it contains an absolute path to a header:
#include "/home/user/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/x86_64-linux/ruby/config.h"
Because this file and directory does not exist on my system, compiling the source code fails.
I assume if I change this to point at my personal location of config.h, it will succeed but then fail on others' systems.
Is there a way to point at some symbolic link that the system will then use the proper location for such a file? What is the best way to approach this situation?
Change it to #include "ruby/config.h", and then add -I/home/user/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/x86_64-linux/ (or whatever your location is) to your compiler options. This tells the preprocessor to add that directory to the list of directories to search when looking for #includes.
To solve the portability you can then change whatever generates the makefile to take this path as an option/argument, or you can just put it in a variable at the top of the makefile and ask people to change it:
RUBY_LOCATION = /home/user/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/x86_64-linux/
CFLAGS = -Wall -I${RUBY_LOCATION}

Including a library (lsusb) in a C program

I am still fairly new to programming with C and I am working on a program where I want to control the power to various ports on a hub I have. That is, however, not the issue I am having right now.
I found a program online that does what I want I am trying to compile it. However it uses #include<lsusb.h>. lsusb is located in a totally different folder than the file I am wanting to run (and not in a sub folder) and when I try to compile it, I, logically enough, get the error that the file lsusb.h is not found.
How can I link to this file so that it can be found?
This is more of a GCC toolchain question than a C question (although most C compilers do use the same Unixy flags).
The braces around the include file (<>) indicate you want the compiler to search its standard search path for the include file. So you can get access to that new include file either by putting it into a directory on your standard include file search path yourself, or by adding its directory to the file search path. With GCC you do the latter by giving gcc the flag -I"directoryname" where "directoryname" is the full file path to where you are keeping that new include file of yours.
Once your compiler finds it, your linker may have the exact same problem with the library file itself ("liblsusb.a"?). You fix that the same way. The flag GCC's linker will want is -L instead of -I.
See the "-I" parameter in the gcc man page. It allows you specify a directory in which to find a header file. See also -l and -L.
Or try #include "../../path_to_the_file/lsusb.h"

Resources