In my iOS project I need to use an external library written in C++. The C++ header files are all in one directory.
I've added these C++ headers to my Xcode project, and also specified a header search path (in Build Settings).
The issue is that these C++ headers include each other using < > angle brackets. This results in:
'filename.h' file not found with <angled> include, use "quotes" instead.
The weird thing is that Xcode does not complain about all headers. Also the same header #include'd in one file is fine, while an issue when #include'd in another. I think this is caused by the fact that these headers #include each other.
Why doesn't the search path work?
Is there a way to resolve this without modifying these header files?
Thanks!
#include <bla.h>
is meant for standard library or framework headers, and the search strategy
Is different than that used for
#include "bla.h"
See for example
What is the difference between #include <filename> and #include "filename"?
As a workaround, you can set the Xcode build setting "Always Search User Paths" to YES.
Starting from a "blank" application project:
Create a folder "Libraries" in your application's project - preferable as a sibling to your MyApp.xcodeproj file, but it can be anywhere. Create subfolders for each Configuration (Debug, Release, etc.) and possibly for each architecture (armv7, armv7s, arm64) unless the binary is universal binary archive containing all architectures.
Get the headers of the third party library and the static library binaries (possibly more than one for different platforms, Configurations and architectures) and move them into the "Library" folder into corresponding subfolders (which you may need to create):
For example, assuming you had a universal binary (armv7, armv7s, arm64) and Debug and Release versions of that library:
Now, the folder structure is assumed to be as follows:
$(SRCROOT)/Libraries
Debug-iphoneos
include
ThirdParty
third_party.hh
...
libThirdParty.a
Release-iphoneos
include
ThirdParty
third_party.hh
...
libThirdParty.a
MyApp.xcodeproj
"Library Search Paths" Build Setting:
Drag the "Libraries" folder into your Xcode project. This may automatically create a library search path in the build settings. Please verify this, and if it is not correct, fix it.
Given the example, add the following library search paths for Debug and Release Configuration:
Debug: Library Search Paths: $(SRCROOT)/Libraries/Debug-iphoneos
Release: Library Search Paths: $(SRCROOT)/Libraries/Release-iphoneos
You may have different library search paths for particular Configuration and Target platform pairs. Set different path's in the build setting accordingly.
"Header Search Paths" Build Setting:
Given the example, add the following header search path to the Debug and the Release Configuration:
Debug: Header Search Paths: $(SRCROOT)/Libraries/Debug-iphoneos/include
Release: Header Search Paths: $(SRCROOT)/Libraries/Release-iphoneos/include
Likewise, you may have different paths for particular Config/Target pairs - although the headers may be the same.
Link your app against the C++ standard library by adding -lc++ to the Other Linker Flags build setting.
Import the header in your files as follows:
#import <ThirdParty/third_party.hh>
In Xcode 9, I need to add header files path to the Header Search Paths build setting, not User Header Search Paths.
Xcode will append User Header Search Paths to compile command as -iquote options, but append Header Search Paths as -I options. That's the key difference.
In XCode after setting the "User Header Search Paths" to point to your library's directory, you also have to make sure that a field called "Always Search User Paths" is set to "Yes"
This solved the problem I was having: with <boost/signals2.hpp> file not found with <angled> include, use "quotes" instead.
my two cents for OSX / Mysql.
(by the way I ask why that bogus use of <> in mysql... anyway..)
As per Xcode 11 warning, "Disabling it is strongly recommended.",
I prefer to patch another setting, leaving "Always Search User Paths" to "No".
I set:
HEADER_SEARCH_PATHS = "/usr/local/mysql/include".
LINKER:
I)
If You got link error, add "libmysqlclient.a" usually in "/usr/local/mysql/lib", simply dragging from Finder)
II: You can get a worst error...
"/usr/local/lib/libmysqlclient.21.dylib: code signature in (/usr/local/lib/libmysqlclient.21.dylib) not valid for use in process using Library Validation: mapping process and mapped file (non-platform) have different Team IDs"
As that lib is not signed. Simply in Entitlemens:
(in XML):
..
<dict>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
...
Related
My application need boost lib. There is a boost lib in /usr/lib and boost include in /usr/include/boost, but they aren's what I need. So I compile new boost lib in my home , /home/js/anaconda/.../include/boost and /home/js/anaconda/.../lib.
To use boost in home, I use "-I/home/js/anaconda/.../include/boost" to define the include path, however, It complain error because it find boost in the "/usr/..." path. Then I try use "-I/home/js/anaconda/.../include" (the parent directory) and it works fine!
My question is
1)why it works when I specify the parent directory "/home/.../include" instead of "/home/.../include/boost"? what is the right directory I should specify when I use "-I"?
2)when I use "-I" to specify some directory, will these directory always be the one prior to the /usr directory?
It's a common practice (but not mandatory) to include all the header files of a library into its own directory. This has a few advantages:
When you look for a header file, you don't need to look through the header files of other libraries.
When you read a file with include directives, you can see all the headers that belong to the same library because they start in the same base directory.
When you use -I preprocessor flag to add a directory to the include search path, that directory can either:
Belong to your current project: in the case you have your files organised in directories it may become handy.
Be a part of an external dependency: be it a system library or a dependency installed in a directory of your own. These directories' path end in include following the filesystem hierarchy standard.
In the particular case of boost, the intended use is to -I/path-to-boost-install/include flag and then use an include directive such as #include <boost/optional/optional.hpp> to use one of the libraries in that installation.
The best advice is to read the documentation and look for examples before you start using a library. In the case of boost, you can read the getting started on Unix or getting started on Windows pages:
It's important to note the following:
The path to the boost root directory (often /usr/local/boost_1_75_0) is sometimes referred to as $BOOST_ROOT in
documentation and mailing lists .
To compile anything in Boost, you need a directory containing the boost/ subdirectory in your #include path.
Since all of Boost's header files have the .hpp extension, and live in the boost/ subdirectory of the boost root, your Boost #include
directives will look like:
#include <boost/whatever.hpp>
or
#include "boost/whatever.hpp"
depending on your preference regarding the use of angle bracket includes.
I'm getting the following error :
"fatal error C1083: Cannot open include file"
for one of my header files being #included in stdafx.h. I have set the include and library paths in the project dependencies, Tried to include them in additional include section. On top of that when I right click the
#include <BCGCBProInc.h>
it is able to open the file and show it to me. So it can find and open the file but instead gives me the error. I am using VS2012 on Windows 7 and the header is in a different location then the project.
What am I doing wrong / not doing right?
1.
#include <BCGCBProInc.h>
is not the same as
2.
#include "BCGCBProInc.h"
Different search pathes apply to both variants of including a file.
The pathes looked up when using variant 1. are those defined as default search pathes like
/usr/include for IXish systems
$(VCInstallDir)include also called VC++ Directories for VC
The pathes used when using 2. are those added via the option -I (/I for VC).
In Visual Studio, right-click your project and choose Properties. Select the VC++ Directories option in the left pane, and then look at the Include Directories and Library Directories in the right pane. Make sure they are using relative paths and not absolute paths. If they must be absolute paths, then every machine you run this project on will have to have the exact same path. Absolute paths look like this:
D:/Development/MyProject/includes
Relative paths can be done using $(ProjectDir) to make it relative to the project, or $(SolutionDir) to make it relative to the solution (if different from project), and would look something like this:
$(ProjectDir)../includes
or
$(SolutionDir)includes
What I had to do to get it to compile was change
#include "BCGCBProInc.h"
to this
#include "C:\Program Files (x86)\BCGSoft\BCGControlBar Professional Evaluation\BCGCBPro\BCGCBProInc.h"
I'm not sure why because I included the path in the VC++ Directories. When I browse for the path it changes (x86) to %29x86%29 which is what I thoght was screwing it up but that is not the case because I manually changed it back to (x86).
My plan is when I eventually get what i need to get done, I will bring the libs and includes into the project locally and make the paths relative
I've got a CMake project that includes and links against two libraries, say A and B (actually it's more than two and one of them is boost stuff, but that doesn't really matter here). Both are located via FindSomething.cmake scripts that (correctly) populate the standard CMake variables such that include directories are added via
INCLUDE_DIRECTORIES(${A_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${B_INCLUDE_DIRS})
and linking is later done via
TARGET_LINK_LIBRARIES(mytarget ${A_LIBRARIES} ${B_LIBRARIES})
Now, the problem is that both libraries can either reside in a user based location or in the system directories (I'm on linux by the way, CMake 2.8.2) - or in both. Let's say A is only in $HOME/usr/include and $HOME/usr/lib while B (boost in my case) resides in both the system paths (/usr/include and /usr/lib) AND in the user based paths - in different versions. The find scripts can be made to find either the system or the user-based library B, this works.
The trouble starts when I want to link against B from the system paths.${B_INCLUDE_DIRS} and ${B_LIBRARIES} correctly point to the system-wide locations of the headers and libraries. But there is still ${A_INCLUDE_DIRS} that points to a non-system include directory and ultimately also the headers for library B are taken from this location, while the linking for B uses the version from the system paths (via ${B_LIBRARIES}) which leads to conflicts, i.e. linking errors.
Changing the order of the INCLUDE_DIRECTORIES statements does not seem to change anything. I checked the origin of the symbols that cause the linking errors via nm --line-numbers on the object files.
What can I do? Is there a trick to
force the ordering of the include directories (even if this would mean to give precedence to a system path although there is also a user-based location specified)?
tell CMake to use ${A_INCLUDE_DIRS} for all headers from A and ${B_INCLUDE_DIRS} for all headers from B?
Here's what CMake says about include_directories():
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
You can specify that you want to have include directories searched before or after the system include directories at the time that you tell it about those directories.
You may also be specific to a target:
target_include_directories(target [SYSTEM] [BEFORE] [items1...] [ [items2...] ...])
If A and B are different libraries containing different header files and paths, there should be no problem doing what you are doing right now.
That being said, if A and B are similar libraries containing header files of the same name at the same location, that is problematic. In that case, the order of the include_directory() call is important. I ran a little test where I had three copies of a header file. The first copy is located in my system path (say /usr/include). The other copies are located in two user-defined locations (say /tmp/include1 and /tmp/include2). The file in /tmp/include1 is found and used first if I put the include_directory() call in the following order:
include_directory("/tmp/include1")
include_directory("/tmp/include2")
The file in /tmp/include2 is found and used first if I put the include_directory() call in the following order:
include_directory("/tmp/include2")
include_directory("/tmp/include1")
If I put no include_directory() statement, then the header in the system path is found and used.
You may want to re-check how your FindSomething.cmake are written. The search order of the find_*() CMake commands can be found in the CMake documentation,
As far as I can remember, there is now way of telling CMake to use ${A_INCLUDE_DIRS} for all headers from A and ${B_INCLUDE_DIRS} for all headers from B if the header file can be found in both location. It all depends in what order the include_directory() call are made. If the FindSomething.cmake are written properly, if the CMAKE_MODULE_PATH (this is the location where CMake will look for the Find*.cmake files) is set properly and all the paths are good, then you should be good to go. If not, I will need more information on your current CMake/library setup.
When using third party libraries, I would always do this
Library A + B header files:
third_party/include/libA_name/ <-- put header files in there
third_party/include/libB_name/ <-- put header files in there
In source files you would always use it like this
#include "libA_name/file.h" <-- no ambiguity possible
#include "libB_name/file.h" <-- no ambiguity possible
Then you can still use -I "third_party/include" as the include folder and no ambiguity in ordering will happen in source files.
This also disambiguates custom header files from system header files which could clash from time to time from 3rd party libs.
For me this worked fine:
INCLUDE_DIRECTORIES(BEFORE ${A_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${B_INCLUDE_DIRS})
I'm trying to get Xcode to import the header file for Irrlicht.
#include <irrlicht.h>
It says "Irrlicht.h. No such file or directory". Yes Irrlicht.h with a capital I, even though the #include is lowercase.
Anyway I added "/lib/irrlicht-1.6/include" in the header search paths for the Xcode project, yet it still doesn't find it.
The only thing I've tried that does work is:
#include "/lib/irrlicht-1.6/include/irrlicht.h"
This is a bit ridiculous though, #include should work, I don't understand why it isn't working.
Update (here are more details on the error):
/lib/PAL/pal_benchmark/palBenchmark/main.h:31:0
/lib/PAL/pal_benchmark/palBenchmark/main.h:31:22: error: irrlicht.h: No such file or directory
I figured this out. Perhaps someone can comment as to why this is the case.
The Header was located in this directory:
/lib/irrlicht-1.6/include/
If I added that path to: "Header Search Paths" Xcode still wouldn't find the path when I built the project.
Solution: Add the header path to: "User Header Search Paths" instead.
It boggles me why I had to do this, as I frequently add my header paths to "Header Search Paths" and then #includes just work. Hopefully this can help someone else who gets this same issue.
Both
#include <irrlicht.h>
#include "irrlicht.h"
should work as long as the "-I" argument to gcc includes the path of the directory enclosing the header file. If irrlicht.h is part of /usr/include the "-I" option is no longer required.
Rather than explicitly adding include paths to your project settings, an easier and more convenient solution for this kind of situation is to just drag the directory containing your .h files (/lib/irrlicht-1.6/include in this case) into the project files pane. This adds the headers to your project of course, and makes it easy to browse them and search for symbols, etc, and it also adds the directory path to gcc compiles, so that you don't have to manage include paths explicitly.
and furthermore, a flat file hierarchy isn't what you want. Dragging files into Xcode flattens your hierarchy. What about for example when you want to have multiple Targets, with a "TargetName/settings.h" file for that target. you'll have many settings.h files that you need to keep unique via its folder name.
I understand that this is an old post, but it does rank quite high on Google, so I thought I would add some information
Under XCode 3.2.6, I had an issue where XCode could not find a header file. It turns out that one of the filepaths included a space in it, and XCode interpreted it improperly.
For example: With a path like "Users/Username/Desktop/Project/Some Headers"
Here was the excerpt from the GCC Commandline: "-I/Users/Username/Desktop/Project/Some" "-I/Headers"
To see your build log provided by XCode, there is a good tutorial here: How do you show Xcode's build log? (Trying to verify if iPhone distribution build zip was created correctly.)
I am working on a game using Visual C++. I have some components in separate projects, and have set the project dependencies. How do I #include a header file from a different project? I have no idea how to use classes from one project in another.
Settings for compiler
In the project where you want to #include the header file from another project, you will need to add the path of the header file into the Additional Include Directories section in the project configuration.
To access the project configuration:
Right-click on the project, and select Properties.
Select Configuration Properties->C/C++->General.
Set the path under Additional Include Directories.
How to include
To include the header file, simply write the following in your code:
#include "filename.h"
Note that you don't need to specify the path here, because you include the directory in the Additional Include Directories already, so Visual Studio will know where to look for it.
If you don't want to add every header file location in the project settings, you could just include a directory up to a point, and then #include relative to that point:
// In project settings
Additional Include Directories ..\..\libroot
// In code
#include "lib1/lib1.h" // path is relative to libroot
#include "lib2/lib2.h" // path is relative to libroot
Setting for linker
If using static libraries (i.e. .lib file), you will also need to add the library to the linker input, so that at linkage time the symbols can be linked against (otherwise you'll get an unresolved symbol):
Right-click on the project, and select Properties.
Select Configuration Properties->Linker->Input
Enter the library under Additional Dependencies.
Since both projects are under the same solution, there's a simpler way for the include files and linker as described in https://learn.microsoft.com/en-us/cpp/build/adding-references-in-visual-cpp-projects?view=vs-2019 :
The include can be written in a relative path (E.g. #include "../libProject/libHeader.h").
For the linker, right click on "References", Click on Add Reference, and choose the other project.
Expanding on #Benav's answer, my preferred approach is to:
Add the solution directory to your include paths:
right click on your project in the Solution Explorer
select Properties
select All Configurations and All Platforms from the drop-downs
select C/C++ > General
add $(SolutionDir) to the Additional Include Directories
Add references to each project you want to use:
right click on your project's References in the Solution Explorer
select Add Reference...
select the project(s) you want to refer to
Now you can include headers from your referenced projects like so:
#include "OtherProject/Header.h"
Notes:
This assumes that your solution file is stored one folder up from each of your projects, which is the default organization when creating projects with Visual Studio.
You could now include any file from a path relative to the solution folder, which may not be desirable but for the simplicity of the approach I'm ok with this.
Step 2 isn't necessary for #includes, but it sets the correct build dependencies, which you probably want.
#include has nothing to do with projects - it just tells the preprocessor "put the contents of the header file here". If you give it a path that points to the correct location (can be a relative path, like ../your_file.h) it will be included correctly.
You will, however, have to learn about libraries (static/dynamic libraries) in order to make such projects link properly - but that's another question.
You need to set the path to the headers in the project properties so the compiler looks there when trying to find the header file(s). I can't remember the exact location, but look though the Project properties and you should see it.
Try to avoid complete path references in the #include directive, whether they are absolute or relative. Instead, add the location of the other project's include folder in your project settings. Use only subfolders in path references when necessary. That way, it is easier to move things around without having to update your code.