How to use LLVM library in c++ Xcode project? - c++

I'm loosely following the tutorial to implement Kaleidoscope on the LLVM website, and I'm at the point where I need to actually use the LLVM library for code generation. I've installed LLVM 13 using homebrew (brew install llvm), but I can't figure out how to use it in a c++ project in Xcode. I just get the error 'llvm/whatever/whatever' file not found for every file I try to include:
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
I've tried adding the include folder (/opt/homebrew/Cellar/llvm/13.0.1_1/include for me) to the header search paths in Xcode, which seems to do something but I end up with the error Undefined symbol: llvm::DisableABIBreakingChecks, and hundreds of different warnings.
All I want is to be able to use LLVM code generation in a small c++ project. Is there any simple way to do this?

I'm also doing that tutorial. I'll tell you how I got it to work, but since I'm not an LLVM expert, I don't know if this is the best way.
I checked out and built LLVM from source, as described here. Installing with brew like you did should also work fine.
Next, I looked at the build command they give in the tutorial:
clang++ -g -O3 toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core`
-o toy
I can run that llvm-config command from my build directory and it gives me the flags that I need to somehow give to Xcode.
> bin/llvm-config --cxxflags --ldflags --system-libs --libs core
-I/Users/rob/Foo/llvm-project/llvm/include
-I/Users/rob/Foo/llvm-project/build/include
-std=c++14 -fno-exceptions -fno-rtti
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-L/Users/rob/Foo/llvm-project/build/lib
-Wl,-search_paths_first -Wl,-headerpad_max_install_names
-lLLVMCore -lLLVMRemarks -lLLVMBitstreamReader
-lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle
-lm -lz -lcurses -lxml2
I put those -I paths in the HEADER_SEARCH_PATHS build setting, and the -L path in LIBRARY_SEARCH_PATHS. In Xcode those values are a list of paths, so you add the paths without the -I or -L part. I then put the -l library arguments in OTHER_LDFLAGS, and the -D arguments in OTHER_CPLUSPLUSFLAGS.
After that, it compiled and ran from Xcode. I did not yet translate all of the output from llvm-config into Xcode build settings. For example, I did nothing about these:
-std=c++14 -fno-exceptions -fno-rtti
-Wl,-search_paths_first -Wl,-headerpad_max_install_names
Remains to be seen if that will cause problems later.

Related

Xcode linker flags for GSL

I am trying to use the GSL library with C++ in Xcode and I was having an issue linking to the library.
I am able to link to GSL using the terminal and clang with the following linker flags
clang++ -std=c++17 -Wall -pedantic test.cpp -o test -lgsl -lgslcblas
From the command line I'm able to verify it uses the GSL library for the computation. However in Xcode, I get a "'gsl/gsl_linalg.h' file not found" error when I try to build it. Its called in my header file with
#include <gsl/gsl_linalg.h>
I added -lgsl -lgslcblas into Xcode build settings thru the "Other Linker flags" option.
I also ran
gsl-config --cflags
gsl-config --libs
and got the following output
-I/usr/local/include
-L/usr/local/lib -lgsl -lgslcblas
So it seems like GSL is installed properly and can be used by clang but for some reason when I use clang through Xcode it isn't able to use it. I was also able to manually find that particular header file in /usr/local/include/gsl/gsl_linalg.h
Any ideas on what I'm might be doing wrong?

Kaleidoscope tutorial cannot find header `ExecutorProcessControl.h`

To follow Kaleidoscope tutorial part 4, I downloaded the header file KaleidoscopeJIT.h. But once I include it, I get the following error
$ clang++ -g main.cpp kaleidoscope.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native` -O3 -o kaleidoscope
In file included from kaleidoscope.cpp:18:
././include/KaleidoscopeJIT.h:21:10: fatal error: 'llvm/ExecutionEngine/Orc/ExecutorProcessControl.h' file not found
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
The closest information to it I could find at documentation page, but there is no information on how to successfully compile it. Any suggestions on how to resolve header dependency?
Here are my config options,
$ llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native
-I/usr/lib/llvm-10/include -std=c++14 -fno-exceptions -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-L/usr/lib/llvm-10/lib
-lLLVM-10
Make sure you pull the correct files. You are using llvm-10 so you need to use the kaleidoscope tutorial from that version.

Trouble compiling code from LLVM Kaleidoscope tutorial

When I used g++ -std=c++17 toy.cpp -o toy to compile the toy.cpp file without the header #include "llvm/ADT/STLExtras.h" in the toy.cpp file, everything was fine and I produced a "working" binary file.
However, when I added the #include "llvm/ADT/STLExtras.h" line to the toy.cpp file and compile it with the command g++ -std=c++17 toy.cpp -o toy, the terminal crushed me with the following output:
-bash: llvm-config: command not found
toy.cpp:1:10: fatal error: 'llvm/ADT/STLExtras.h' file not found
#include "llvm/ADT/STLExtras.h"
The same thing still happens even if I used
"clang++ -g -O3 toy.cpp llvm-config --cxxflags --ldflags --system-libs --libs core -o toy"
instead of "clang++ -g -O3 toy.cpp llvm-config --cxxflag" in the tutorial. My guess is that there's something wrong with the llvm-config thing. It's been bothering me for a while, please teach me how to solve it.
Link to the toy.cpp code
The answer to this is "llvm-config" is not working as expected.
Just check with which llvm-config to figure out whether you got this program. (mine is /usr/local/opt/llvm#8/bin/llvm-config). Or you can install with brew install llvm.
By the way, I came up with the same issue lately on kaleidoscope tutorial (ch2), but I want to know why the #include "llvm/ADT/STLExtras.h fails after several attempts on $(llvm-config --cxxflags --ldflags), etc or we aren't able to compile following chapter's code simply by removing the header declaration when llvm include files are necessary.

'"SDL.h" no such file or directory found' when compiling

Here's a piece of my current Makefile:
CFLAGS = -O2 -Wall -pedantic -std=gnu++11 `sdl-config --cflags --libs` -lSDL_mixer
I have libsdl installed properly, SDL.h is in /usr/include/sdl where it belongs, but it just won't compile. I also have the line #include "SDL.h" in my .h files, but still no go.
Anyone knows why?
For Simple Direct Media Layer 2 (SDL2), after installing it on Ubuntu 16.04 via:
sudo apt-get install libsdl2-dev
I used the header:
#include <SDL2/SDL.h>
and the compiler linker command:
-lSDL2main -lSDL2
Additionally, you may also want to install:
apt-get install libsdl2-image-dev
apt-get install libsdl2-mixer-dev
apt-get install libsdl2-ttf-dev
With these headers:
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL_mixer.h>
and the compiler linker commands:
-lSDL2_image
-lSDL2_ttf
-lSDL2_mixer
If the header file is /usr/include/sdl/SDL.h and your code has:
#include "SDL.h"
You need to either fix your code:
#include "sdl/SDL.h"
Or tell the preprocessor where to find include files:
CFLAGS = ... -I/usr/include/sdl ...
header file lives at
/usr/include/SDL/SDL.h
__OR__
/usr/include/SDL2/SDL.h # for SDL2
in your c++ code pull in this header using
#include <SDL.h>
__OR__
#include <SDL2/SDL.h> // for SDL2
you have the correct usage of
sdl-config --cflags --libs
__OR__
sdl2-config --cflags --libs # sdl2
which will give you
-I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT
-L/usr/lib/x86_64-linux-gnu -lSDL
__OR__
-I/usr/include/SDL2 -D_REENTRANT
-lSDL2
at times you may also see this usage which works for a standard install
pkg-config --cflags --libs sdl
__OR__
pkg-config --cflags --libs sdl2 # sdl2
which supplies you with
-D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL -lSDL
__OR__
-D_REENTRANT -I/usr/include/SDL2 -lSDL2 # SDL2
Most times SDL is in /usr/include/SDL. If so then your #include <SDL.h> directive is wrong, it should be #include <SDL/SDL.h>.
An alternative for that is adding the /usr/include/SDL directory to your include directories. To do that you should add -I/usr/include/SDL to the compiler flags...
If you are using an IDE this should be quite easy too...
the simplest idea is to add pkg-config --cflags --libs sdl2 while compiling the code.
g++ file.cpp `pkg-config --cflags --libs sdl2`
Having a similar case and I couldn't use StackAttacks solution as he's referring to SDL2 which is for the legacy code I'm using too new.
Fortunately our friends from askUbuntu had something similar:
Download SDL
tar xvf SDL-1.2.tar.gz
cd SDL-1.2
./configure
make
sudo make install

Compiling the cal3d demo "cally" (3d model library with boned animations)

I think this is a question about automake.
http://home.gna.org/cal3d/
I'm struggling with the cally demo of Cal3D.
The first problem I ran into was that the Cal3D code base is missing #include <cstring> and #include <memory> in a lot of places.
Doing this every time I got an error in any source file in Cal3d was enough to let me compile it.
The cally demo also needed some #include <cstring>
Now my problem is that HAVE_SDL_H is not defined when tick.cpp is compiled.
The configure and makefile seems to accept that SDL is installed on my system, but the macros in src/tick.cpp doesn't.
I guess there is some kind of bug in the configure.in or something, but I don't seem to find out just what it is.
if g++ -DHAVE_CONFIG_H -I. -I. -I.. -O3 -ffast-math -funroll-all-loops -g -O2 -I/usr/include -I/usr/local/include -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -MT tick.o -MD -MP -MF ".deps/tick.Tpo" -c -o tick.o tick.cpp; \
then mv -f ".deps/tick.Tpo" ".deps/tick.Po"; else rm -f ".deps/tick.Tpo"; exit 1; fi
tick.cpp:144:5: error: #error "no timer implemented for your plateform"
Edit:
I've finally compiled the demo.
When I compiled cal3d I added #include <cstring> to the following files:
src/cal3d/hardwaremodel.cpp
src/cal3d/platform.cpp
src/cal3d/renderer.cpp
src/cal3d/submesh.cpp
src/cal3d_converter.cpp
When I compiled cally I added #include <cstring> to the following files:
src/demo.cpp
src/model.cpp
In model.cpp I changed line 640 from
glBindTexture(GL_TEXTURE_2D, (GLuint)pCalRenderer->getMapUserData(0));
to
glBindTexture(GL_TEXTURE_2D, *(GLuint*)pCalRenderer->getMapUserData(0));
I also did some uglier changes to get src/tick.cpp to compile.
In src/tick.cpp I removed everything that had anything to do with SDL. I also removed a macro if clause checking for __i386__ or __ia64__, so that Tick::getTime() could also be compiled.
I know that this is not a proper fix, so improvements are very much welcome.
64-bit OpenSuSE with a 2.6.27 kernel.
GCC: 4.3.2
GNU Automake: 1.10.1
GNU Autoconf 2.63
64-bit versions of the SDL library is installed with zypper (through the GUI).
Solution
In configure.in change
AC_CHECK_HEADERS([SDL.h])
to
AC_CHECK_HEADERS([SDL/SDL.h])
(then run autoreconf and ./configure)
in tick.cpp change all checks for HAVE_SDL_H to HAVE_SDL_SDL_H
This is all due to a restructuring in the sdl library.
The errors you got with missing #include <cstring> and #include <memory> is mainly du to a cleanup that happened in GNU headers: inclusion of unnecessary headers were removed and consequently programs not including the proper headers for the features they use face compiling errors.
About HAVE_SDL_H, most likely, your Linux distribution is missing packages.
You probably need to install the SDL library. Some Linux distributions like Ubuntu split the packages between the library runtime and the dev files so you need to install both packages
sudo apt-get install libsdl1.2-dev
Regarding:
if g++ -DHAVE_CONFIG_H -I. -I. -I.. -O3 -ffast-math -funroll-all-loops -g -O2 -I/usr/include -I/usr/local/include -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -MT tick.o -MD -MP -MF ".deps/tick.Tpo" -c -o tick.o tick.cpp; \
then mv -f ".deps/tick.Tpo" ".deps/tick.Po"; else rm -f ".deps/tick.Tpo"; exit 1; fi
tick.cpp:144:5: error: #error "no timer implemented for your plateform"
It indeed fails to compile because HAVE_SDL_H is not defined in config.h. When you look at configure.in you see it's using AC_CHECK_HEADERS([SDL.h])
From the autoconf manual:
— Macro: AC_CHECK_HEADERS (header-file..., [action-if-found], [action-if-not-found], [includes])
For each given system header file header-file in the blank-separated argument list that exists, define HAVE_header-file (in all capitals). If action-if-found is given, it is additional shell code to execute when one of the header files is found. You can give it a value of ‘break’ to break out of the loop on the first match. If action-if-not-found is given, it is executed when one of the header files is not found.
So, AC_CHECK_HEADERS([SDL.h]) makes configure search for SDL.h in /usr/include and doesn't find it because its (new?) path is /usr/include/SDL/SDL.h
As a workaround, use CPPFLAGS to add system header search paths when invoking configure:
./configure CPPFLAGS="-I/usr/include/SDL"
Now you may want to fix configure.in
configure.in uses AM_PATH_SDL(1.2.0) which will end up invoking sdl-config --cflags to define SDL_CFLAGS. (the implementation of AM_PATH_SDL typically lies in the /usr/share/aclocal/sdl.m4 file)
# Check for SDL
AM_PATH_SDL(1.2.0)
LDFLAGS="$LDFLAGS $SDL_LIBS"
CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
AC_CHECK_HEADERS([SDL.h])
AC_LANG_CPLUSPLUS
sdl-config --cflags returns -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT but those -I and -D directives should not end up in CFLAGS anyway but rather in CPPFLAGS (as per the autoconf manual). Hence I would say there is already something wrong "at the SDL level".
Now take a look at the AC_LANG documentation:
‘C’
Do compilation tests using CC and CPP and use extension .c for test programs. Use compilation flags: CPPFLAGS with CPP, and both CPPFLAGS and CFLAGS with CC.
‘C++’
Do compilation tests using CXX and CXXCPP and use extension .C for test programs. Use compilation flags: CPPFLAGS with CXXCPP, and both CPPFLAGS and CXXFLAGS with CXX.
Moving the AC_LANG_CPLUSPLUS up so that it at least above AC_CHECK_HEADERS([SDL.h]) should make it now use g++ and CXXFLAGS when trying to compile SDL.h which should success since SDL_CFLAGS were added to CXXFLAGS. (again, it should really be SDL_CPPFLAGS but you won't change SDL...)