A commit in the C implementation of the Nokogumbo gem is causing the build to fail on Gentoo Linux, however, the modification is minor and shouldn't cause any trouble. Unfortunately, I know next to zilch about C.
Here's the commit:
https://github.com/rubys/nokogumbo/commit/8b4446847dea5c614759684ebcae4c580c47f4ad
It simply replaces the <> with "":
-#include <gumbo.h>
-#include <error.h>
-#include <parser.h>
+#include "gumbo.h"
+#include "error.h"
+#include "parser.h"
According to the GCC docs this shouldn't cause any trouble since it falls back to the previous behaviour:
#include "file"
This variant is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the quote directories and then the same directories used for <file>. You can prepend directories to the list of quote directories with the -iquote option.
Unfortunately, while it compiles just fine with <>, the build fails with "":
compiling nokogumbo.c
nokogumbo.c:24:20: fatal error: parser.h: No such file or directory
#include "parser.h"
I'm wondering to what degree the way <> and "" behaves depends on the toolchain, environment and other settings.
Thanks a lot for your hints!
Re-installing "gumbo" on the Gentoo box has fixed the problem. Apparently, a local installation mess has produced this weird behaviour.
I checked your git repository and I noticed that you compile code with --std=c99. I think this may cause the problem, Because I found this in C99 draft:
The named source file is searched for in an implementation-defined
manner .If this search is not supported, or if the search fails, the
directive is reprocessed as if it read
#include <header>
So it means process is first implementation defined, and if not supported it uses #include<> mode. But this means if it defines that #include"" searches current directory, it will stop searching like #include<>.
Related
My OS is ArchLinux, and write a simple program which just includes <uapi/linux/ptrace.h>:
#include <uapi/linux/ptrace.h>
void main(void) {}
The compilation complains:
test.c:1:10: fatal error: uapi/linux/ptrace.h: No such file or directory
#include <uapi/linux/ptrace.h>
^~~~~~~~~~~~~~~~~~~~~
compilation terminated.
I check /ust/include/uapi directory, and find it is empty. Finally, I find the correct uapi position is /usr/lib/modules/4.11.9-1-ARCH/build/include/uapi. So what is the canonical way of using <uapi/linux/..> in ArchLinux? Create a new link which points to /usr/lib/modules/4.11.9-1-ARCH/build/include/uapi or put the path into C_INCLUDE_PATH? They all seem a little weird.
TL;DR: pacman -S linux-api-headers and #include <linux/ptrace.h>
UAPI stands for User API and is the name of a folder in the kernel sources that is intended to be copied to an installation as part of the user-accessible kernel headers. In the case of Arch, some of these headers are copied to /usr/include/linux/ (plus some generated files on kernel compilation). But this is not part of the default install, it is actually separated in a different package: linux-api-headers (after installing, you can use #include <linux/ptrace.h>).
There is no /usr/include/uapi and this is by design, the contents of the original uapi folder are directly copied into /usr/include.
So, unless you are programming a kernel module, what you are probably looking for is #include <linux/ptrace.h>.
I know it is possible to specify #include filepaths either relative to the directory the file is located in, as an absolute file path, or relative to any of the directories in the $PATH system variable. Is there a way to instead specify it relative to the user's current directory when the program is compiled? Let's say I have the following file structure:
|--dir_a/
| |--a.c
| |--a.h
|--dir_b/
| |--b.c
| |--b.h
|--makefile
Now let's say I want to #include the file dir_a/a.h from dir_b/b.h. Using the location of dir_b/b.h, this can be written like this:
#include ../dir_a/a.h
However, this approach has a major flaw in my opinion since it hardcodes the locations of files relative to each other, meaning that relocating a file would require updating the file path everywhere that file was included from.
Using absolute file paths would avoid this problem, but would instead hardcode the location of the project within the filesystem, which seems like bad practice.
Finally, using the <> tags to specify the file path isn't feasible either since I can't assume the project will be listed in the $PATH variable.
So what I want to do is to be able to specify the paths relative to where the user compiles from (or even better, from the location of the makefile). In the above example, this would let me use the following statement to #include dir_a/a.h from dir_b/b.h:
#include dir_a/a.h
This I think would be the ideal solution. It would make the #include statements more consistent and easier to follow, as well as avoid the drawbacks I listed above. Is it possible to do this in any way, eg. with a compiler flag or something? I'm using gcc as my compiler.
If you consistently use <> includes, then the -I options in the makefile should be enough. The directory layout shows only one makefile, in the parent directory. That could use
-Idir_a -Idir_b
in the compiler options, and the .c files could just do
#include <a.h>
#include <b.h>
One of the problems with quoted includes is that their behavior with other compilers may differ, as noted in What is the difference between #include <filename> and #include “filename”? (the standard was not explicit enough). Using a gcc extension probably does not improve that situation.
I managed to solve my problem.
The first part of the solution involves specifying the -iquote flag in gcc when compiling. From man gcc:
-iquotedir
Add the directory dir to the head of the list of directories to be searched for header files only for the case of #include "file"; they are not searched for #include <file>, otherwise just like -I.
The second part of the puzzle was how to get the path to the makefile within the makefile itself. This answer worked for me. I'm pasting the solution here for convenience:
ROOT_DIR = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
edit: While this approach works, this answer is more cross-compiler friendly, so I'm personally going to use that.
Yes. Any include file, which is not directly in your include path specified in your project linker settings, should have all subfolders up to it specified, like:
#include "first/second/third/folder/library.h"
I am on OS X 10.10 and trying to build a C 'project' with GLUT and OpenGL.
I reduced it to a minimal example showcasing my problem. I have the following CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
FIND_PACKAGE(OpenGL REQUIRED)
FIND_PACKAGE(GLUT REQUIRED)
if(OpenGL_FOUND) # never true, but printed as true
link_directories(${OpenGL_LIBRARY_DIRS})
include_directories(${OpenGL_INCLUDE_DIR})
endif(OpenGL_FOUND)
if(GLUT_FOUND)
link_directories(${GLUT_LIBRARY_DIR})
include_directories(${GLUT_INCLUDE_DIR})
endif(GLUT_FOUND)
# print all vars because wtf
get_cmake_property(_v VARIABLES)
foreach(_v ${_v})
message(STATUS "${_v}=${${_v}}")
endforeach()
add_executable(main main.c)
target_link_libraries(main ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
The main.c is just a dummy including two headers:
#include <gl.h>
#include <glut.h>
int main()
{
return 0;
}
Now, cmake . runs fine and for debugging purposes prints all variables. I took the code from somewhere, I do not know enough about cmake to know whether it's doing what I think it is. Anyway, running make returns
main.c:1:10: fatal error: 'gl.h' file not found
#include <gl.h>
^
1 error generated.
The header gl.h is actually present in /System/Library/Frameworks/OpenGL.framework/Headers and as such should be found by cmake, especially since glut.h is in the same structure (simply replace OpenGL with GLUT) and is found just fine. Also, what is confusing to me is that the block in if(GLUT_FOUND)... is never executed (try to put a message statement into it), but among the printed variables it says OPENGL_FOUND=TRUE. But removing the if-condition does not change anything.
The actual question: What the hell is going on? Why does a) cmake not find the header unless specifically included, b) the if-block not execute although OPENGL_FOUND prints as TRUE, c) no such problems occur with glut.h? Spent hours on this and can't fathom why.
It's common to do
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
You can see this being done in one form or another in glfw, glew, sfml and others
I'm surprised that you found OpenGL headers in /System/Library/Frameworks in OS X 10.10. I don't think they have been installed there in quite a few Xcode releases. The most recent header files with Xcode 6.1 on 10.10 should be in:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks/OpenGL.framework/Headers
You don't really need to know this path, unless you want to go look at the headers. I believe the compiler automatically uses the SDK that matches the OS you're compiling on. If for some reason you wanted to build for a different platform, you can override that logic with the -isysroot compiler option.
With header files that come from a framework, the naming you use in your #include statement is:
#include <FrameworkName/HeaderFileName.h>
The compiler will resolve this to the actual pathname of the header within the framework.
Therefore, if you want to use the current OpenGL header, which is gl3.h, from the OpenGL framework, the correct include statement is:
#include <OpenGL/gl3.h>
This will give you access to the Core Profile of the highest supported OpenGL version (which is 3.x or 4.x if you have a reasonably new Mac). Or if you want to use OpenGL 2.1 with legacy features:
#include <OpenGL/gl.h>
As pointed out bei pmr, CMake variables are case-sensitive, so the variable OPENGL_FOUND must be queried.
Also, as PeterT wrote, the header is included as #include <OpenGL/gl.h> on OS X.
I ended up coming to this question after updating qt installed from homebrew and had the same error messages. Going off of Reto's comment, I updated CMAKE_OSX_SYSROOT to /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk and everything went back to working as expected.
My understanding was always that by doing #include <header.h> it looks in the system include directories, and that #include "header.h" it looks in the local directory. But I was just looking at the python source code and it uses the "header.h" method to define headers in a sibling directory.
So in py3k/Python/ast.c it does #include "Python.h". But Python.h is in py3k/Include/Python.h
Is this something common that I've just never seen, not having worked on any real large C project? How do I tell, at least my IDE, to look in py3k/Include?
Update
I figured out how to tell my IDE to include them, it was just me being stupid and a spelling error. But I'm more interested in why "" works. Is that not the different between "" and <>?
Both #include <header> and #include "header" look in "implementation-defined places", i.e. it depends on the compiler you are using and its settings. For #include <h> it's usually some standard system include directories and whatever you configure the compiler to look in additionally.
The difference between the two versions is that if the search for #include "header" is not supported or fails, it will be reprocessed "as if it read #include <header>" (C99, §6.10.2).
You need to somehow tell your compiler what directories to search in -- for GCC this means using the -I flag. Look it up for your combination of IDE / compiler.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
what is the difference between #include <filename> and #include “filename”
In both cases there is no error ...Is there any difference between them ?
<stdio.h> searches in standard C library locations, whereas "stdio.h" searches in the current directory as well.
Ideally, you would use <...> for standard C libraries and "..." for libraries that you write and are present in the current directory.
The second version is specified to search first in an implementation defined location, and afterwards if the file is not found, search in the same place as the <...> version, which searches in the paths usually specified by the -I command line option and by built-in include paths (pointing to the location of the standard library and system headers).
Usually, implementations define that location to be relative to the location of the including file.
The <> tell the compiler to look for the file in the libraries' headers and "" tell it to look around among your application's headers.
As for why both of them works for you, maybe your compiler also looks for the filename in the library headers in case it didn't find one among yours.
You use #include when you want to say: "look for a file with this name in the system's include directory". You use #include "doublequoted" when you want to say: "look for a file with this name in my own application's include directory; however, if it can't be found, look in the system's include directory".
#include <something.h> is meant for system headers, while #include "something.h" is for headers of your own program. System headers are searched for in usual system directories (and those included with -I argument), which your headers are searched for in current directory and then the same locations as system headers.
see http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC6
For the compilers I've used, "..." starts looking for the include file in the same directory as the source file that is being compiled, then the include path. Includes with <...> start in the include path, skipping the current die unless it is in the include path.
Normally standard header files are enclosed by < > and other user specific files are specifed with " .
I case of "..." compiler first search the header file in your local directory where
your .c file presents
while in case of <...> compiler only search in header file folder
The difference is that header files made by the developer are enclosed by "". Header files that are already in the system are enclosed with <>. Even the <> headers need the -I directive if the directories that are placed are not in the search path of the compiler.
Bottom line: Your headers with "", system headers with <>
<stdio.h> refers to a header (not a header file)
"stdio.h" refers to a source file.
Headers need not exist phisically in the implementation; the way they are identified is implementation-defined (usually the headers are files on specific directories)
When the directive uses ", the source file is searched in an implementation-defined manner and, if not found, the directive is reprocessed as if it was written with < and > in the first place.