I am trying to compile a C program which uses regexes on FreeBSD. I have checked in /usr/local/include and the file pcre.h is definitely there.
However, no matter what I do, I get the following compiler error:
/usr/home/myname/project/include/pcre_wrap.h:4:18: error: pcre.h: No such file or directory
What could be going wrong? My understanding of C libraries on Unix could be better...
As the comment above says you need to use #include. If this isn't working you may want to export an environment variable C_INCLUDE_PATH that points to the header file.
Failing that why not try adding -I/usr/local/include to your gcc call, something like gcc myfile.c -I/usr/local/include -o myexe
Related
I am attempting to compile this code:
#include <GLFW/glfw3.h>
int main() {
glfwInit();
glfwTerminate();
return 0;
}
Using this command in MSYS2 on Windows 10:
gcc -Wall runVulkan.c -o runVulkan
as well as this:
gcc -Wall -Llibs/glfw runVulkan.c -o runVulkan
libs/glfw is where I downloaded the library to.
For some reason I keep getting this:
runVulkan.c:1:10: fatal error: GLFW/glfw3.h: No such file or directory
1 | #include <GLFW/glfw3.h>
| ^~~~~~~~~~~~~~
compilation terminated.
It seems like I'm getting something very basic wrong.
I'm just getting started with C, I'm trying to import Vulkan libraries.
Run pacman -S mingw-w64-x86_64-glfw to install GLFW.
Then build using gcc -Wall runVulkan.c -o runVulkan runVulkan.c `pkg-config --cflags --libs glfw3`.
The pkg-config command prints the flags necessary to use GLFW, and the ` backticks pass its output to GCC as flags. You can run it separately and manually pass any printed flags to GCC.
Note that any -l... flags (those are included in pkg-config output) must be specified after .c or .o files, otherwise they'll have no effect.
For me pkg-config prints -I/mingw64/include -L/mingw64/lib -lglfw3.
-I fixes No such file or directory. It specifies a directory where the compiler will look for #included headers. Though it's unnecessrary when installing GLFW via pacman, since /mingw64/include is always searched by default.
-l fixes undefined reference errors, which you'd get after fixing the previous error. -lglfw3 needs a file called libglfw3.a or libglfw3.dll.a (or some other variants).
-L specifies a directory where -l should search for the .a files, though it's unnecessrary when installing GLFW via pacman, since /mingw64/lib is always searched by default.
#include are just headers, for declarations. gcc, as any compilers, needs to know where those .h should be searched.
You can specify that with -I option (or C_INCLUDE_PATH environment variable).
You'll also need -L option, this times to provide the library itself (.h does not contain the library. Just declarations that the compiler needs to know how to compile codes that use the library function's and types).
-L option tells the compiler where to search for libraries.
But here, you haven't specify any libraries (just headers. And I know that it seems logical that they go together. But strictly speaking, there is no way to guess from #include <GLFW/glfw3.h> which library that file contain headers for (that is not just theory. In practice, for example, the well known libc declarations are in many different headers)
So, you will also have to specify a -l option. In your case -lglfw.
This seems over complicated, because in your case you compile and like in a single command (goes from .c to executable directly). But that are two different operations done in one command.
Creation of an executable from .c code source is done in two stage.
Compilation itself. Creating .o from .c (many .c for big codes), so many compilation commands. Using command such as
gcc -I /path/where/to/find/headers -c mycode.c -o mycode.o
Those are not related to the library. So no -l (and therefore no -L) for that. What is compiled is your code, so just your code is needed at this stage. Plus the header files, because your code refers to unknown function and types, and the compiler needs to know, not their code, but at least declarations that they really exist, and what are the types expected and returned by the functions is the headers files.
Then, once all the .o are compiled, you need to put together all compiled code, yours (the .o) and the libraries (which are somehow a sort of .zip of .o) to create an executable. That is called linking. And is done with commands like
gcc -o myexec mycode1.o mycode2.o -L /path/where/to/search/for/libraries -lrary
(-lbla is a compact way to include /path/where/to/search/for/libraries/libbla.so or /path/where/to/search/for/libraries/libbla.a)
At this stage, you no longer need -I or anything related to headers. The code is already compiled, headers has no role left. But you need everything needed to find the compile code of the libraries.
So, tl;dr
At compilation stage (the stage that raises the error you have for now), you need -I option so that the compiler knows where to find GLFW/glfw3.h
But that alone wont avoid you the next error that will occur at linking stage. At this stage, you need -lglfw to specify that you want to use that library, and a -L option so that the compiler knows where to find a libglfw.so
I am doing the CS50 class, I have installed the cs50.h.
Based on the instructions I used the following command in terminal to compile my simple program and just want to make sure I understand everything im asking terminal to do.
Line is:
gcc -g hello.c -o hello -lcs50 -lm
I know the following*: gcc =
gcc = gnu compiler for C
-g = generate source-level debug information
Hello.c = name of the file we want to compile
-o = write output file
hello = our output file name
Can anyone tell me what -lcs50 and -lm are? My guess is that its calling on the library lcs50 in (-lcs50) but again this is a guess and would like to know for sure.
Everything works as it should with no issues
Thanks,
Mostly correct.
-o is not required to generate the output file, it's only needed to customize the name. (-o and the following name can only appear together).
-lcs50 means "link the library called cs50", not lcs50. It will try to find this file using several different name patterns, e.g. libcs50.so (on Linux), [lib]cs50.dll[.a] (on Windows), libcs50.a (on both), something else on Mac.
-lm links the standard math library, but I don't think you need to manually specify it on most modern GCC distributions.
Yes. For -lm, it's for the maths library, which is not linked by default. This is explained well at Why do you need an explicit `-lm` compiler option.
I'm trying to compile a simple unit test on my windows machine.
When I'm trying to compile my test I'm using the shared library flag.
gcc -c -L./bin/ -lcmocka .\Test.c .\src\some_module.c
gcc .\Test.o .\some_module.o -o main
But the second line throws this error:
undefined reference to `_cmocka_run_group_tests'
However, if I'm compiling using directly the cmocka.c file which I downloaded from their git it works fine:
gcc -c .\lib\cmocka.c .\Test.c .\src\some_module.c
gcc .\Test.o .\some_module.o .\cmocka.o
What am I doing wrong in the first compilation?
In addition, I would happy to understand the difference between the two compilations. Which one is the better practice?
Thank you
In order to compile your code, the compiler does not need to know where to look for the library. It's enough if the compiler "finds" the declarations of the functions which are usually in the header files provided by the library.
This step is done in the first line of your compilation procedure (maybe you need to specify the folder to the header files by adding -Ipath/to/headers/):
gcc -c .\Test.c .\src\some_module.c
The library itself is "combined" with your code during the linking step, which is done during your second compilation step. Here you need to specify the library (and its path via -Lpath/to/library, if the linker does not find the library on its own):
gcc .\Test.o .\some_module.o -o main -L./bin/ -lcmocka
You should definitely not use your second approach and compile the library by yourself.
I have a simple, representative C program, stored in a file called hello.c:
#include <stdio.h>
int main(void)
{
printf('Hello, world\n');
return 0;
}
On my Linux machine, I attempted to compile the program with gcc:
gcc hello.c
which returns an error:
undefined reference to "___gxx_personality_v0" ... etc
As has been discussed before in the context of C++, this problem arises in the linking stage, when gcc attempts to link C libraries to a C++ program, thus giving the error. In one of the answers, someone mentioned that the extension does matter, and that gcc requires the .c extension when compiling C files, and some other extension (e.g. .cpp) when compiling C++ files.
Question: How do I set gcc to use the file extension to determine which compiler to use, since gcc seems to be defaulting to C++ on my system? Specifying the language through the file extension alone doesn't seem to be enough. If I specify the language using the -x flag, gcc functions as expected.
gcc -x c hello.c
Typically, you let make decide this.
GNU Make has built in implicit rules, which automatically pick the right compiler.
Try a Makefile with these contents:
all: some_file.o some_other_file.o
And then place a some_file.cpp and some_other_file.c in the same directory, and gnu make will automatically pick the correct compiler. The linker, you may still have to provide yourself. When mixing C and C++, it's usually easiest to link with g++, like so:
program.exe: some_file.o some_other_file.o
g++ -o $# #^
This is the same as:
program.exe: some_file.o some_other_file.o
g++ -o program.exe some_file.o some_other_file.o
This is the header file and its C file:
cs50.h and
cs50.c
Now I use them in the following example http://www.paste.ubuntu.com/576370/ — which is no longer available.
I already put the header file in /usr/bin/include or something like that and when I try to compile my code using gcc -o xxx xxx.c, it doesn't work, so tried to fix this and the following way worked: http://www.paste.ubuntu.com/576371/ — which is no longer available.
Now I want to do something to make the 'make' command work as the gcc does.
What do I need to do?
The following was the old topic:
I was using gcc command to
compile C programs but after a period
of time I got a problem. I need
to compile a new header file and use
it as a library.
The header file called cs50.h.
so after doing it and it's ok I can
compile using the following
gcc -o xxx xxx.c -lcs50
It works but now I want to use 'make'
command and I can't get it to work.
It just don't compile the header file
and library as gcc was before I edit
it to accept the cs50 library.
So now I want to add to the 'make'
command the following: -lcs50
Can anyone help me in this please?
Near the top of your Makefile, add the line:
LDLIBS = -lcs50
If you are using Make's default (implicit) rules for the building, then that is all you need to do. If you are using explicit rules, you will need to add $(LDLIBS) to your explicit rules.
If there is no Makefile, then make is using default rules, and you can either just create a makefile with
echo LDLIBS = -lcs50 > Makefile
or tell make to link with certain libraries by specifying the required libraries in LDLIBS in the environment. For example, if you are using a sh-derived shell (anything other than csh or tcsh) you can do:
LDLIBS=-lcs50 make target
If you are using a csh variant, you can do:
env LDLIBS=-lcs50 make target
or just do (again, for non-csh shells)
export LDLIBS=-lcs50
before running make. (For csh variants, do setenv LDLIBS -lcs50)
You can use below “make” command to link library and include header directories,
make <.c or .cpp source filename_without_extension> LDLIBS="-l<lib1> -l<lib2>"
suppose you have server.cpp file to compile using make command,
make server LDLIBS="-lcpprest -lpthread -lssl -lcrypto" LDFLAGS="-L/usr/lib/" CXXFLAGS="-I/usr/include/"
Output will expand the compilation command as,
g++ -I/usr/include/ -L/usr/lib/ server.cpp -lcpprest -lpthread -lssl -lcrypto -o server
Did you forget that you have to tell gcc in what directory the CS50 library is located?
gcc … -L/directory/for/cs50_library -lcs50