flycheck header file not found, but makefile is correct - c

I'm using emacs with flycheck to check C source code syntax and trying to get it working with glib. My code compiles and runs correctly, however flycheck reports a file not found error in the #include <glib.h> line and stops reporting further errors, defeating its purpose.
Here's my sample source file:
#include <stdio.h>
#include <glib.h>
GList* list = NULL;
int main() {
list = g_list_append(list, "a");
list = g_list_append(list, "b");
list = g_list_append(list, "c");
for ( ; list!=NULL; list=list->next) {
printf("%s\n", (char*)list->data);
}
return 0;
}
And the makefile
P=glist
OBJECTS=
CFLAGS=-g -Wall -O3 `pkg-config --cflags glib-2.0`
LDLIBS=`pkg-config --libs glib-2.0`
CC=gcc-4.9
$(P): $(OBJECTS)
If I change the include line to read #include <glib-2.0/glib.h> I get the following error reported in the minibuffer:
Checker c/c++-clang returned non-zero exit code 1, but no errors from
output: In file included from
/var/folders/f/ts3zs3cjbq1fqfhdfrl1w0000gn/T/flycheck87881gVK/glist.c:2:
/usr/local/include/glib-2.0/glib.h:32:10: error: 'glib/galloca.h' file
not found with include; use "quotes" instead In file included
from
/var/folders/_f/ts3_zs3cjbq1fqfhdfrl1w0000gn/T/flycheck87881gVK/glist.c:2:
In file included from /usr/local/include/glib-2.0/glib.h:32:
/usr/local/include/glib-2.0/glib/galloca.h:34:10: fatal error:
'glib/gtypes.h' file not found
Checker definition probably flawed.
Still the code compiles and runs correctly. I'm not sure why it can't find glib/gtypes.h as it exists under one of the included directories. The output from pkg-config --cflags glib-2.0 is:
-I/usr/local/Cellar/glib/2.36.4/include/glib-2.0 -I/usr/local/Cellar/glib/2.36.4/lib/glib-2.0/include -I/usr/local/opt/gettext/include
Listing ls /usr/local/Cellar/glib/2.36.4/include/glib-2.0/glib/gtypes.h
/usr/local/Cellar/glib/2.36.4/include/glib-2.0/glib/gtypes.h
And listing ls /usr/local/include/glib-2.0/glib/gtypes.h
/usr/local/include/glib-2.0/glib/gtypes.h
So the file is there. I wouldn't mind switching to flymake if flycheck is to blame, but I'm not sure if it's a problem with my setup or flycheck itself. Plus flycheck configuration is dead simple and otherwise works very well. I'm using version 20130904.2245 installed from elpa.

Flycheck does not use Makefiles, nor does it attempt to parse them. I cannot help but wonder how you even got this idea, given that no such behaviour is documented in the manual, and no syntax checker for make files even exists.
Flycheck runs Clang directly. You need to explicitly configure the include path for syntax checking by setting flycheck-clang-include-path accordingly. You must do so yourself, this is not done automatically based on your Makefile.
You can set the path via file/dir local variables, or write some custom Emacs Lisp code to parse your Makefile.

Related

Running Ruby in C compile and link issues

I've been trying all day to build and run a simple Ruby inside of C program.
This is a recurring topic here, and none of them are identical to my issue nor have any of the solutions helped me. I have the ruby-dev installed.
The pkg-config command gives this:
$ pkg-config --cflags --libs ruby-2.7
-I/usr/include/x86_64-linux-gnu/ruby-2.7.0 -I/usr/include/ruby-2.7.0 -lruby-2.7 -lm
The compile command gives this:
$ gcc -I/usr/include/x86_64-linux-gnu/ruby-2.7.0 -I/usr/include/ruby-2.7.0 -I. -lruby-2.7 -o hello *.c
/usr/bin/ld: /tmp/ccdKXtnU.o: in function 'main':
hello.c:(.text+0x9): undefined reference to 'ruby_setup'
collect2: error: ld returned 1 exit status
I have tried switching up the order of the includes. I have tried removing one then the other include. I have tried using a Makefile and running it thru make. I have tried breaking the program up into multiple files. I have tried symbolically linking the architecture relative config.h file into the main header file directory.
The only thing I can think of that I haven't tried is putting the name of the ruby object library that needs to be linked in on the command line, but I don't know the name, or location, of that file.
Here's the latest rendition of the program:
#include <stdio.h>
#include <ruby.h>
int main(void)
{
if (ruby_setup()){
puts("Hola!");
}
else{
printf("Hello World\n");
}
return(0);
}
One of the reasons that pkg-config separates cflags and libs is that they go in different places in the command-line (and sometimes different commands).
If you're going to compile and link in one command, it goes like this:
c99 -o hello $(pkg-config --cflags ruby-2.7) *.c $(pkg-config --libs ruby-2.7)
There's a certain logic to this arrangement. First, we tell the compiler where to look for header files (which it must see before it compiles your program), then where to find the program to compile, and finally where to find the libraries which are referred to by the program.

Linux : Glib was not found

I have a sample C project that use GLib Library. In that source code, it use :
#include <glib.h>
When I compile, I found this error : "Glib.h : no such file or folder". I have google and find out that I should install this lib. So I use those command:
apt-get install libgtk2.0-dev
apt-get install glade
After that, I have checked and see already exist this header file in my system: usr/include/glib-2.0/glib.h But when I compile, I still meet problem above.
So I have change include line to :
#include <glib-2.0/glib.h>
So, after that, when I compile, I meet error inside glib.h header :
#ifndef __G_LIB_H__
#define __G_LIB_H__
#define __GLIB_H_INSIDE__
#include <glib/galloca.h>
#include <glib/garray.h>
// more code here
glib/galloca.h : no such file or directory. Because this error is inside system header file, I cannot modify anymore and still cannot compile.
I don't know how to fix this. I have read some post, that they change makefile. But, because my project is compiled automatically by IDE (CodeBlock) and I cannot really write a makefile, so that method doesn't suitable for me.
Please tell me a way to fix this.
Thanks :)
There must be some problem with how you build. To compile C programs that use GLib, you need package libglib2.0-dev. You can either install it directly, or install libgtk2.0-dev, which pulls it in as a dependency. So you have the packages you need.
The correct way to compile a GLib program is to use -I with the path to the GLib include files.
An example (from How to compile a helloworld GLib program? on askubuntu):
gcc $(pkg-config --cflags --libs glib-2.0) hello_glib.c
This should let you compile this program:
#include <stdio.h>
#include <glib.h>
int main(int argc, char** argv) {
GList* list = NULL;
list = g_list_append(list, "Hello world!");
printf("The first item is '%s'\n", g_list_first(list)->data);
return 0;
}
The errors you are getting indicate that you are not setting the include path (-I) correctly. How to do this depends on your build system/IDE.
In Code::Blocks, you must set the include path and the linker options in the appropriate configuration dialog. Run pkg-config --cflags --libs glib-2.0, which will output something like
-I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -lglib-2.0
The directories after -I must be set in the compiler options of your project (should be under Project -> Build Options -> Search Directories), and the names after -l must be set in the linker settings. Another option is to create a Makefile, and let Code::Blocks use that.
See e.g. Q: What do I need to know when using 3rd party libs? in the Code::Blocks Wiki.
You should not alter your source code (e.g. the #include directives).
You just need to use pkg-config (both for compiling, with --cflags, and for linking, with --libs), preferably with a builder program like make.
This is an example for exactly your situation: a Makefile using pkg-config to compile some source program using glib

Linking libsrtp problems

I installed libsrtp on my ubuntu machine according to the directives in read me, the tests worked fine, and the rptw utility included in libsrtp worked perfectly too. But when I tried to include srtp.h in my HelloWorld! program, it gives me an error that:
fatal error: srtp.h: No such file or directory
compilation terminated.
Concretely, my main file is this
#include "srtp.h"
int main()
{
return 0;
}
My libsrtp.a is present in /usr/local/lib/lib
I used this gcc statement from this blog:
gcc -static main.c -L/usr/local/lib/lib/ -llibsrtp -o main
I will be deeply grateful for any help.
You've found your libsrtp.a , but where is srtp.h ? You'll need to tell the compiler where to search for included files if it's not in a standard location with the -I flag.
Perhaps you need a -I/usr/local/include or -I/usr/local/include/srtp
Note also that -llibsrtp is likely wrong, you need to give the name without the lib prefix. So that makes it -lsrtp

Still get 'curl/curl.h: No such file or directory' in spite of all looks proper

I installed on windows curl 7.28.0 from curl-7.28.1-devel-mingw32.zip through minGW console to default directory like:
./config && make && make install
All needed headers (aka curl.h, types.h ...) I see in C:\MinGW\msys\1.0\local\include\curl
libcurl.pc placed in C:\MinGW\msys\1.0\local\lib\pkgconfig\
libcurl.a, libcurl.dll.a and libcurl.la placed in C:\MinGW\msys\1.0\local\lib.
My download_file.c file includes are:
...
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
...
I try to compile the C code with followed command through gcc:
$ gcc -IC:/MinGW/msys/1.0/include/
-IC:/MinGW/msys/1.0/local/include/curl
-IC:/MinGW/msys/1.0/local/lib/pkgconfig
-o download_file download_file.c -llibcurl -lcurl
with absolute path get the same error:
gcc -I/include/
-I/local/include/curl
-I/local/lib/pkgconfig
-o download_file download_file.c -llibcurl -lcurl
But I still get an error:
download_file.c:21:23: fatal error: curl/curl.h: No such file or directory compilation terminated.
row 21 is #include <curl/curl.h>
What I did wrong? Please help.
You have the curl/ directory in the source code, but also in the option.
It seems the option should point out the higher-level directory in which curl/ is, so it should be something like:
-I/local/include/
I think the problem is likely that you give your include paths on the command line in the Win32 path format. This is not the same as the one used by msys (or ultimately Cygwin).
Try these:
$ gcc -I/include/
-I/local/include/curl
-I/local/lib/pkgconfig
...
Hope I got the absolut paths right, but you can check in your msys shell.
What ticked me off was that you use ./config, which wouldn't work from the Command Prompt, but works from the msys shell. So you need to give paths that all the programs in MinGW understand.
Basically, most programs in MinGW only have the concept of a single file system root, like on any unixoid system, while Win32 has multiple (the drive letters). Since the MinGW programs are linked accordingly, you need to give paths that they understand.
Thank you very much to #0xC0000022L and #unwind. By your help I fixed my problem.
0xC0000022L you are right about absolute path
unwind you are right about -I/local/include/ instead -I/local/include/curl
I found other problem: -L/local/lib instead -I/local/lib.
So this is a working command:
gcc -I/include/
-I/local/include
-L/local/lib
-o download_file download_file.c -llibcurl -lcurl

Include an external library in C

I'm attempting to use a C library for an opencourseware course from Harvard. The instructor's instructions for setting up the external lib can be found here.
I am following the instructions specific to ubuntu as I am trying to use this lib on my ubuntu box. I followed the instructions on the page to set it up, but when I run a simple helloWorld.c program using a cs50 library function, gcc doesn't want to play along.
Example:
helloWorld.c
#include <stdio.h>
#include <cs50.h>
int
main(void){
printf("What do you want to say to the world?\n");
string message = GetString();
printf("%s!\n\n", message);
}
$ gcc helloWorld.c
/tmp/ccYilBgA.o: In function `main':
helloWorld.c:(.text+0x16): undefined reference to `GetString'
collect2: ld returned 1 exit status
I followed the instructions to the letter as stated in the instructions, but they didn't work for me. I'm runing ubuntu 12.04. Please let me know if I can clarify further my problem.
First, as a beginner, you should always ask GCC to compile with all warnings and debugging information enabled, i.e. gcc -Wall -g. But at some time read How to invoke gcc. Use a good source code editor (such as GNU emacs or vim or gedit, etc...) to edit your C source code, but be able to compile your program on the command line (so don't always use a sophisticated IDE hiding important compilation details from you).
Then you are probably missing some Harvard specific library, some options like -L followed by a library directory, then -l glued to the library name. So you might need gcc -Wall -g -lcs50 (replace cs50 by the appropriate name) and you might need some -Lsome-dir
Notice that the order of program arguments to gcc is significant. As a general rule, if a depends upon b you should put a before b; more specifically I suggest
Start with the gcc program name; add the C standard level eg -std=c99 if wanted
Put compiler warning, debugging (or optimizing) options, eg -Wall -g (you may even want to add -Wextra to get even more warnings).
Put the preprocessor's defines and include directory e.g. -DONE=1 and -Imy-include-dir/
Put your C source file hello.c
Put any object files with which you are linking i.e. bar.o
Put the library directories -Lmy-lib-dir/ if relevant
Pur the library names -laa and -lbb (when the libaa.so depends upon libbb.so, in that order)
End with -o your-program-name to give the name of the produced binary. Don't use the default name a.out
Directory giving options -I (for preprocessor includes) and -L for libraries can be given several times, order is significant (search order).
Very quickly you'll want to use build automation tools like GNU make (perhaps with the help of remake on Linux)
Learn also to use the debugger gdb.
Get the habit to always ask for warnings from the compiler, and always improve your program till you get no warnings: the compiler is your friend, it is helping you!
Read also How to debug small programs and the famous SICP (which teaches very important concepts; you might want to use guile on Linux while reading it, see http://norvig.com/21-days.html for more). Be also aware of tools like valgrind
Have fun.
I take this course and sometimes I need to practice offline while I am traveling or commuting. Under Windows using MinGW and Notepad++ as an IDE (because I love it and use it usually while codding python) I finally found a solution and some time to write it down.
Starting from scratch. Steps for setting up gcc C compiler, if already set please skip to 5
Download Git and install. It includes Git Bash, which is MINGW64 linux terminal. I prefer to use Git as I need linux tools such as sed, awk, pull, push on my Windows and can replace Guthub's terminal.
Once Git installed make sure that gcc packages are installed. You can use my configuration for reference...
Make sure your compiler works. Throw it this simple code,
by saving it in your working directory Documents/Harvard_CS50/Week2/
hello.c
#include <stdio.h>
int main(void)
{
printf("Hello StackOverflow\n");
}
start Git Bash -> navigate to working directory
cd Documents/Harvard_CS50/Week2/
compile it in bash terminal
gcc helloworld.c -o helloworld.exe
execute it using bash terminal
./helloworld.exe
Hello StackOverflow
If you see Hello StackOverflow, your compiler works and you can write C code.
Now to the important bit, installing CS50 library locally and using it offline. This should be applicable for any other libraries introduced later in the course.
Download latest source code file cs50.c and header file cs50.h from https://github.com/cs50/libcs50/tree/develop/src and save them in Documents/Harvard_CS50/src
Navigate into src directory and list the files to make sure you are on the right location using
ls
cs50.c cs50.h
Cool, we are here. Now we need to compile object file for the library using
gcc -c -ggdb -std=c99 cs50.c -o cs50.o
Now using the generated cs50.o object file we can create our cs50 library archive file.
ar rcs libcs50.a cs50.o
After all this steps we ended with 2 additional files to our original files. We are interested in only 2 of them cs50.h libcs50.a
ls
cs50.c cs50.h cs50.o libcs50.a
Copy Library and header files to their target locations. My MinGW is installed in C:\ so I copy them there
cs50.h --> C:\MinGW\include
libcs50.a --> C:\MinGW\lib
Testing the cs50 Library
To make sure our library works, we can throw one of the example scripts in the lecture and see if we can compile it using cs50.h header file for the get_string() method.
#include <stdio.h>
#include <cs50.h>
int main(void)
{
printf("Please input a string to count how long it is: ");
string s = get_string();
int n = 0;
while (s[n] != '\0')
{
n++;
}
printf("Your string is %i chars long\n", n);
}
Compile cs50 code using gcc and cs50 library. I want to be explicit and use:
gcc -ggdb -std=c99 -Wall -Werror test.c -lcs50 -o test.exe
But you can simply point the source, output filename and cs50 library
gcc test.c -o test.exe -lcs50
Here we go, program is compiled using header and methods can be used within.
If you want Notepad++ as an IDE you can follow this tip to set it up with gcc as a compiler and run your code from there.
Just make sure your nppexec script includes the cs50 library
npp_save
gcc -ggdb -std=c99 -Wall -Werror "$(FULL_CURRENT_PATH)" -lcs50 -o "$(CURRENT_DIRECTORY)\$(NAME_PART).exe"
cmd /c "$(CURRENT_DIRECTORY)\$(NAME_PART).exe"
Download the cs50 from: http://mirror.cs50.net/library50/c/library50-c-5.zip
Extract it. (You will get two files cs50.c and cs50.h)
Now copy both the files to your default library folder. (which includes your stdio.h file)
Now while writing your program use: #include < cs50.c >
You can also copy the files to the folder containing your helloWorld.c file.
You have to use: #include " cs50.c ".
OR =====================================================================>
Open cs50.c and cs50.h files in text editor.
In cs50.h, just below #include < stdlib.h > add #include < stdio.h > and #include < string.h > both on new line.
Now open cs50.c file, copy everything (from: /**Reads a line of text from standard input and returns the equivalent {from line 47 to last}) and paste it in cs50.h just above the #endif and save the files.
Now you can copy the file cs50.h to either your default library folder or to your current working folder.
If you copied the file to default folder then use: #include < cs50.h > and if you copied the files to current working folder then use: #include " cs50.h ".
You need to link against the library during compilation. The library should end in .a or .so if you are on Ubuntu. To link against a library:
gcc -o myProgram myProgram.c -l(library name goes here but no parentheses)
You have to link against the library, how come GCC would know what library you want to use?
gcc helloWorld.c -lcs50
Research Sources:
building on the answers above given by Basile Starynkevitch, and Gunay Anach
combined with instructions from some videos on youtube 1 2
Approach:
covering the minimum things to do, and sharing the "norms" separately
avoiding any modification to anywhere else on the system
including the basic breakdown of the commands used
not including all the fine details, covering only the requirements absolute to task or for effective communication of instructions. leaving the other mundane details to the reader
assuming that the other stuff like compiler, environment variable etc is already setup, and familiarity with shell's file navigation commands is there
My Environment:
compiler: gcc via msys2
shell: bash via msys2
IDE: doesnt matter here
Plan:
getting the source files
building the required files: *.o (object) and *.a (archive)
telling the compiler to use it
Action:
Let's say, current directory = "desktop/cs50"
It contains all the *.c files like test-file.c which I will be creating for assignments/problem sets/practise etc.
Get the *.h and *.c files
Source in this particular case: https://github.com/cs50/libcs50/tree/main/src
Go over each file individually
Copy all the content of it
Say using "Copy raw contents" icon of individual files
Create the corresponding file locally in the computer
Do it in a a separate folder just to keep things clean, let's say in "desktop/cs50/src" aka ./src
Build the required files using in the terminal after changing your current directory to "desktop/cs50/src" :
gcc -c cs50.c to create the "cs50.o" object file from "cs50.c" using "gcc"
ar cr libcs50.a cs50.o to create "libcs50.a" archive file which'll be containing "cs50.o" object file
Here, "libcs50" = "lib" prefix + "cs50" name (same as the header file's name)
This is the norm/standard way where the prefix "lib" is significant as well for a later step
However, prefix can be skipped, and it's not compulsory for name to match the header file's name either. Though, Skipping prefix is not recommended. And I can't say for sure about the name part
To tell the compiler to be able to use this infrastructure, the commands will be in following syntax after going to the parent directory (i.e. to "desktop/cs50"):
gcc test-file.c -Isrc -Lsrc -lcs50 if you used "lib" prefix in step 2.2 above
here, -I flag is for specifying the directory of *.h header file included in your test_file.c
and -L flag is for specifying the directory to be used for -l
and -l is for the name of the *.a file. Here the "lib" prefix talked about earlier, and ".a" extension is not mentioned
the order of these flags matter, keep the -I -L -l flags after the "test-file.c"
Some more notees:
don't forget to use the additional common flags (like those suggested above for errors etc)
if you skipped the "lib" prefix, then you can't use -L -l flags
so, syntax for command will become: gcc test-file.c -Isrc src/libcs50.a
say i created my test-file.c file in "desktop/cs50/psets", so, it can be handled in 2 notable ways (current dir = "desktop/cs50/") :
cd psets then changing the relative address correspondingly in -I -L, so result:
gcc test-file.c -I../src -L../src -lcs50
keeping current directory same, but then changing the file's relative address correspondingly, so result:
gcc psests/test-file.c -Isrc -Lsrc -lcs50
or use absolute addresses 😜
as it can be seen that this becomes quite long, that's when build automation tools such as make kick in (though i am accomplishing that using a shell script 😜)

Resources