Setting CMake module search path - macos

I've written a CMake module to find libclang:
find_path(LibClang_INCLUDE_DIR clang-c/Index.h)
find_library(LibClang_LIBRARY NAMES clang)
But I've installed libclang via MacPorts to /opt/local/libexec/llvm-3.0/lib and /opt/local/libexec/llvm-3.0/include. Since this isn't a normal system location, CMake doesn't find it.
What's the best way to show CMake where it is? How can I find out where CMake is searching? I don't think moving the library to a more normal location is an option because I don't want to move things away from where MacPorts put them, and I also have Apple's official clang binaries (not including libclang) on my system.

Add the HINTS or PATHS flag to suggest locations for it to search.
If you want to make a general way to include non-standard locations, you can do two things. One is make sure the users know to put the non-standard location on the LD_LIBRARY_PATH environment variable and then suggest that as a HINT to find_path and find_library with ENV LD_LIBRARY_PATH.
The other option is to put a custom environment variable and tell users to set that if it's non-standard. For instance, CLANG_ROOT, and include that in the HINTS.
Of course, you can do both and it would be the most general.

Related

using my own static/dinamic library: HOW TO compile and link against (the right way to do the things properly)

Sorry for this newbie question.
Context:
I have just created my own library (using CMake):
libmyownsomething.a <--- static version of the compiled library
libmyownsomething.so <--- dinamic version of the same library
libmyownsomething.h <--- the header file to be included in other project
Questions:
Where is the right place where the files should be placed? ( I guest /usr/local/include/ and /usr/local/lib/
How to compile other lib/projects against this one by inserting only #include <myownsomething.h> and a right flag LDFLAGS=-lmyownsomething?
To be able to link agains your library with just -lmyownsomething, you need to have libmyownsomething.so (or .a, for static linking) in one of the directories you linker searches by default.
I found this in texinfo documentation for GNU ld (library search path in linker script):
'SEARCH_DIR(PATH)'
The 'SEARCH_DIR' command adds PATH to the list of paths where 'ld'
looks for archive libraries. Using 'SEARCH_DIR(PATH)' is exactly
like using '-L PATH' on the command line
Now, GNU ld (ld.bfd to be precise) uses a default linker script, which can be obtained with --verbose. Let's see what search dirs there are by default (on my system, anyways -- that might well depend on configuration; if you are going to distribute your library, you probably want to make the most portable choice):
$ ld --verbose |& grep SEARCH_DIR
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib");
To answer the question about #includeing files, you need to consult the compiler documentation, or perhaps the POSIX standard. (However, I'd recommend either going with the simplest choices -- see below -- or providing a configurable way to install your files e.g. with --prefix build time option. Then the user/packager can decide the best place to put them for themselves. But nothing keeps you from providing sane defaults. Same goes for libraries, but I tried to address that part of the question exactly how it was asked.)
Generally, this stuff varies from system to system, but they usually follow the Filesystem Hierarchy Standard. I think, /usr/include and /usr/lib is the safest choice. Another good practice is using e.g. pkgconf mechanism.
Hope this helps. I really should have asked about your use-case first: who are you going to distribute your software to, and how? Anyway, be sure to post comments. Also, I wonder if this is Stackoverflow material; perhaps it needs moving some place else.

CMake not finding SDL - Windows

I am trying to build a program that requires SDL. I have downloaded SDL for Windows so that I have a folder containing the include and lib suborders.
When I run CMake I get the following error:
Could NOT find SDL (missing: SDL_LIBRARY SDL_INCLUDE_DIR)
This is despite the fact that I have created two environment variables called SDL_LIBRARY and SDL_INCLUDE_DIR, pointing to the lib and include folders respectively.
I have no idea what to do.
In my experience, the best method when find scripts don't work as expected is to check their source code. Often you will identify the problem by just reading through the documentation at the top, but if that still doesn't work out, digging into the source is often the only thing that helps.
From the documentation alone you can see for instance, that CMake does only consider one environment variable SDLDIR for searching. SDL_INCLUDE_DIR and SDL_LIBRARY are the names of the CMake variables to hold the results of the find script. You can set them via the command line (or the cmake-gui), but I would advise against that, as it kind of undermines the purpose of using a find script in the first place.
Instead, verify that your directory structure corresponds to what the find script expects and simply set SDLDIR accordingly.
Please note that the script that currently ships with CMake does not work with the newer SDL2. If you are using SDL2, you will have to write your own script.

Environment variables that one should update when using a new compiler

Say a system admin provides a new version of the gcc compiler available on /some/path on a machine where I build software (all types of software including open source, 3rd party tools, my own programs, etc.):
I usually update the following three environment variables $PATH, $LD_LIBRARY_PATH and $MANPATH, according to what I understand is standard practice for interfacing with general building tools (e.g. autoconf, cmake, etc.) or scripts.
setenv MY_GCC /some/path
setenv PATH $MY_GCC/bin:$PATH
setenv LD_LIBRARY_PATH $MY_GCC/lib64:$LD_LIBRARY_PATH
setenv MANPATH $MY_GCC/share/man:$MANPATH
Here I have a quick question: is there really a reason to update LD_LIBRARY_PATH (why would programs link against a compiler?).
But more generally, what environment variables should one update upon the installation of a new compiler to guarantee a proper building environment?
It depends.
Generally, you do not need to set up any environment variables other than PATH to have a proper building environment (and if you use an IDE, not even that may be necessary, though you might have to tell the IDE where to find the compiler if it lives in an unexpected, non-standard location).
If you use something like autoconf (or CMAKE, or any similar thing), and especially if you have several compiler versions (or cross compilers) on the system, you may want to set variables like CC or CXX to a reasonable default just to be sure (and modify them accordingly if you want something else).
Though if your compiler has its target appended to its name (as in most builds), this is probably not necessary. At least, it works perfectly well for me without doing anything special.
If English is not your native language and your GCC was built with locale support (most stupid idea ever, if you ask me), you may want to set LC_ALL to "C". Otherwise you'll notice that your "unreadable" error messages won't get you much help if you ask for a compiler problem on a forum.
If you have a ramdisk (or SSD) in addition to a normal harddisk, but your projects are on the normal harddisk, you may want to set TMPDIR (even if you always compile with -pipe, since this sometimes seems to create temp files anyway for a reason I don't understand).
If you have non-standard locations for libraries that you want to use, you can set LIBRARY_PATH, but I advise against it. It is better to have your build scripts (or project settings in the IDE) such that these locations are given to the linker on the commandline (or passed through configure with something like --with-foo-path=...). This guarantees that your projects build everywhere and anywhere without requiring someone else to performa a magic dance with some unknown, obscure environment variables. The same goes for C_INCLUDE_PATH.

Add runtime library search paths to pre built binary

I'm trying to package a pre built binary into a Mac OS application bundle and I need to change the dylib and framework search paths for the executable. Unfortunately I can't rebuild the binaries at this point which makes means I have to find a work arround rather than using the correct search paths from the outset. Does anybody know how I can do this?
I assume that you want a permanent change to the executable. You can get temporary changes using the environment variables described in dyld(1). But for a permanent change, you can modify the executable using install_name_tool(1). See Creating Working dylibs for a good short writeup on how to do it. See the dyld(1) page for the replaceable variables you can use, such as #executable_path and #loader_path.

RPATH must exist at compile time

Please forgive me if I'm missing something obvious here. I'm developing some applications for another platform, and all of my proprietary libraries are installed to /app/lib. To facilitate this, I specify a runtime library path for each of my binaries as "/app/lib". This works fine; however, it requires that the path "/app/lib" exist in my build environment when linking (even though that directory is empty). I'm using NetBeans, which might be complicating matters, but I can see "-Wl, -rpath /app/lib" being passed to gcc.
I'd like to avoid the need to create an empty "/app/lib" in my build environment, but I don't want to change the file structure on my target platform. If I delete /app/lib from the build environment, I get an error when building that it can't be found. Is there a way to specify a runtime search path without the need for it to exist at link time?
I think the option you are looking for is -Wl,-rpath-link,/path/to/libraries. You need to use both options at once.
The linker will then use -rpath-link to find the libraries at link-time, but it'll encode the -rpath value into the binary for use at run time.
The syntax should be "-Wl,-rpath -Wl,/app/lib" ("-Wl,-rpath,/app/lib" works too). This is a bug in NetBeans. The reason why it's not more critical (and why I didn't notice this before) is that link-time search paths appear to carry over into runtime. Because NetBeans isn't placing a comma between -rpath and /app/lib, /app/lib is being interpreted as a link-time search path. As a result, my dependent libraries are still found at run-time in the appropriate location, but because it's a link-time dependency, the linking fails because /app/lib doesn't exist.

Resources