Why doesn't Xcode recognize my LIBRARY_SEARCH_PATHS? - xcode

I've set LIBRARY_SEARCH_PATHS to /opt/local/lib, and verified that the library in question is there (I'm linking to GLEW):
$ls /opt/local/lib
libGLEW.1.5.1.dylib libfreetype.a libz.a
libGLEW.1.5.dylib libfreetype.dylib libz.dylib
libGLEW.a libfreetype.la pkgconfig
libGLEW.dylib libz.1.2.3.dylib
libfreetype.6.dylib libz.1.dylib
but Xcode gives me the linker error
library not found for -lGLEW
I'm generating the Xcode project with CMake, so I don't want to explicitly modify the Xcode project (if someone suggests adding it as a framework, or something like that). Xcode recognizes USER_HEADER_SEARCH_PATHS fine (as in this question); why doesn't it work here?

Perhaps adding something like this to your CMakeLists.txt?
find_library(GLEW_LIB GLEW /opt/local/lib)
if(NOT ${GLEW_LIB})
message(FATAL_ERROR "Could not find GLEW")
endif()
target_link_libraries(myprogram ${GLEW_LIB} ...)
Where myprogram is the name of the target executable that needs to link with the library. You would replace the ... with the other libraries you are using on that executable.
This way CMake would handle the library path details for you.

Xcode works on potentially multiple SDK's, so whenever your define these kinds of things (like HEADER_SEARCH_PATHS or LIBRARY_SEARCH_PATHS) the current SDK root is prepended to the actual path that's getting passed to the linker.
So, one way to make this work would be to add your directory to the SDK. For example, assuming you're building with the Mac OS X 10.5 sdk, you could add your opt dir:
ln -s /opt /Developer/SDKs/MacOSX10.5.sdk/opt
Your library would now be found on your system.
If you don't want to do this, then you will have to look at CMake and find out how to get it to generate a library requirement for your actual library (I don't know anything about CMake, so I can't help you there). This is also why you see a difference between USER_HEADER_SEARCH_PATHS and HEADER_SEARCH_PATHS re your other question.
As another option, you could also specify this path with the OTHER_LDFLAGS build variable:
OTHER_LDFLAGS=-L/opt/local/lib
This would cause the linker to search /opt/local/lib as well as its standard paths and wouldn't require you to generate a different project file.

Related

Building a cmake project which uses boost with a local distribution

I'm trying to build kenlm which uses boost. The version of boost already installed on the system seems incompatible or too old or broken.
I have successfully built a copy of boost in my ~/local directory. I would like to tell cmake to use the boost headers found under ~/local/include and the libraries in ~/local/lib instead. However I can't see how to tell cmake to look at my custom path for libraries or headers. I've tried setting LD_LIBRARY_PATH to ~/local/lib:$LD_LIBRARY_PATH. Is there an equivalent variable for include path as well? I haven't been able to find one.
If there is no way to do this with just environment flags, I've been trying to edit the CMakeLists.txt file but haven't had much success. I tried editing in my include path but it still uses whatever find_package(Boost ..) finds which is the /usr/include header.

Statically link OpenSSL in XCode

I am trying to link libssl.a and libcrypto.a static libraries in XCode command line project [under Link Binary With Libraries]. I have included Openssl header files in search path.
Compilation succeeds but execution fails with dyld: Library not loaded: /usr/local/ssl/lib/libcrypto.1.0.0.dylib.
Why does it look for dylib when I am linking it statically? How can this be fixed?
Any help would be appreciable.
Why does it look for dylib when I am linking it statically? How can this be fixed?
Apple's linker uses the dylib or share object if its available, regardless of of your linker flags like -rpath and -Bstatic. They even do it on iOS, where dylib's are not allowed!
Its kind of a well known problem once you know about it :) See, for example, Installing Crypto++ 5.6.2 on Mac OS X. Crypto++ has the same problems with Apple's tools.
The fix is to stop using -L and -l options, and to link the object file or archive directly. An archive is just a collection of object files, so you can use them interchangeably.
To specify the object files or archives for the linker, see Linking to an object file. Under Xcode, you add the fully specified archive name (like /usr/local/openssl-ios/lib/libcrypto.a) to Other Linker Flags (the OTHER_LDFLAGS Xcode option).
When adding the full archive to OTHER_LDFLAGS, I believe you just add it verbatim without any switches, like -l or -L. You may need -Wl (-Wl,/usr/local/openssl-ios/lib/libcrypto.a), but you don't use -l (-l/usr/local/openssl-ios/lib/libcrypto.a).
You use -Wl when the option is passed through the compiler driver to the linker. If the linker is invoked directly, then you don't need -Wl and should not use it.
A second option is to set GCC_LINK_WITH_DYNAMIC_LIBRARIES to YES. Apple does not appear to document it in Xcode Build Setting Reference, but its clearly under my copy of Xcode. See How to link a static library for iOS on Stack Overflow.
I seem to recall having problems with this in the past. Its one of those things that should work in theory, but does not work in practice.
A third option is to remove the dylib or shared object from all paths used under Xcode so Xcode does not accidentally find it when using -lcrypto.
A fourth option is use allow dynamic linking, but execute the program with DYLD_LIBRARY_PATH. Its OS X's equivalent to LD_LIBRARY_PATH, and ensures your copy of OpenSSL is loaded (like 1.0.2), and not the system's version of OpenSSL (0.9.8).
But I don't like this option because it requires users of your software to do something.
Another possibility due to the message dyld: Library not loaded: /usr/local/ssl/lib/libcrypto.1.0.0.dylib is to code sign your copy of the library. Its a little odd its found but not loaded, so I'm going to toss this out there in case its OS X's Code Signing or Gatekeeper Service...
To code sign your copy of the library under the MAC Developer program, just:
codesign -fs "Johnny Developer" /usr/local/ssl/lib/libcrypto.so

CMake: wrong zlib found - how to build zlib from src (with main project CMakeLists.txt) and link it?

// brief version
How can I make CMake to use my supplied zlib (which it also has to build from source) instead of the one found by the finder without breaking the finder for other libs (OpenGL)?
ZLib needs to be used by the main project and also libPNG which comes as source as well.
Primary target platform is Windows.
// longer version:
In my project I need to link against libpng, zlib and OpenGL. With libpng being dependent on zlib. But zlib is also required by the main project.
I need to supply sourcecode for all libs except OpenGL, and build those libraries along with
the main project to assert linking the correct version and simplify building on Windows.
I found ways to do all this with custom libraries where no built-in finder exists, but I can't override the finder properly for just zlib. If I change the search path for libs, then OpenGL is not found.
However I can't get cmake to use my supplied zlib instead of a rouge zlib.DLL that the package finder finds somewhere in my system. (The one from tortoise git)
I tried to set ZLIB_LIBRARY to a specific filepath, but that only works on MinGW, and I also think this is not the way to do it.
(And also I had to explicitly link to png16_static instead of just libpng, for an inexplicable reason.)
Any help on this is much appreciated. Maybe I'm taking this on the wrong way?
Target&Development Platform:
Windows7
Visual Studio 2010
and MinGW (both need to work)
My (simplified example) CMakeLists.txt:
cmake_minimum_required (VERSION 2.6)
project (MyProject)
find_package(OpenGL)
add_executable(MyProject main.cpp)
include_directories(${INCLUDE_DIRECTORIES} "${PROJECT_BINARY_DIR}")
include_directories(${INCLUDE_DIRECTORIES} "external_libs/lpng162")
include_directories(${INCLUDE_DIRECTORIES} "external_libs/zlib-1.2.8")
include_directories(${INCLUDE_DIRECTORIES} "${PROJECT_BINARY_DIR}/external_libs/zlib-1.2.8")
add_subdirectory("external_libs/zlib-1.2.8")
link_directories(${LINK_DIRECTORIES} "${PROJECT_BINARY_DIR}/external_libs/zlib-1.2.8")
# libpng will not build correctly if this not set
set (ZLIB_ROOT "${PROJECT_SOURCE_DIR}/external_libs/zlib-1.2.8")
# manually set this to prevent cmake from finding the tortiose-git zlib.dll first
# DOES NOT WORK CORRECTLY, only with mingw32
set (ZLIB_LIBRARY "${PROJECT_BINARY_DIR}/external_libs/zlib-1.2.8/libzlib.dll")
add_subdirectory("external_libs/lpng162")
TARGET_LINK_LIBRARIES(MyProject png16_static zlib ${OPENGL_LIBRARY})
Project (simplified example) structure:
./main.cpp
./CMakeLists.txt
./external_libs/zlib-1.2.8/ <- contains respective source
./external_libs/lpng162/ <- contains respective source
Third-party libraries most likely call FindZLIB.cmake to determine the location of CMake. You already had the right idea by setting the ZLIB_LIBRARY manually, but were not quite getting it right:
add_subdirectory(<path_to_zlib_src_dir>)
set(ZLIB_INCLUDE_DIR "<path_to_zlib_src_dir>" "${CMAKE_BINARY_DIR}/<path_to_zlib_build_dir>")
set(ZLIB_LIBRARY zlib)
add_subdirectory(<path_to_lpng_src_dir>)
The include directory needs to contain both src and build path as zconf.h is build by CMake
The library name is only the CMake-target name, not the complete path to the resulting file.
On Windows dlls are not automatically copied by CMake. You might want to add some additional code to make sure that the zlib and lpng dlls end up in the right place.
You can call find_package(zlib) yourself to make sure it behaves as expected
In the rare case that a third-party lib does not use the find script, you will have to dig into that project's CMakeLists to find out what is going on

Mac OS X 10.6 : OpenSSL library

I have received an old code on the Mac and trying to compile it on OS X 10.6, in the code there are few calls to OpenSSL library (such as SSL_write()) I added the headers (#include ) in those files and check my version of OpenSSL shows me "0.9.8r" (I know Apple has it's own framework for this library crypto' ) but why I get the Link error as this:
sockets::TcpSocket::TryWrite(char const*, unsigned long) in TcpSocket.o
I know the code should compile against this library in /usr/lib but it doesn't, do I missing path or other setting in Xcode?
There are no libraries in /usr/bin. I assume you mean /usr/lib. You generally do not compile against /usr/lib, however. You usually compile against a specific SDK, which has its own copy of /usr/lib and /usr/include. The SDK header files you use is generally passed in the -isysroot parameter. If you're building in Xcode, these settings are set primarily via the "Base SDK" and "OS X Deployment Target." Without more specifics of how you're building, I'm not certain where else to point you, though. In particular, what does the compile and link lines look like for the relevant file?
In Xcode, don't try to link against specific system libraries by path. You should always link against system libraries using the Link Phase panel of the build settings, and selecting from the SDK list of libraries. Selecting specific paths in the Link Phase panel almost always leads to problems.

Xcode linker error, cannot find lib in /usr/lib

I am getting a linker error in XCode 3.2 where it claims to not be able to find libs in /usr/lib even though LIBRARY_SEARCH_PATHS = "/usr/lib" and the dylib has been added to the xcode project. The later copy build phase of the project manages to find this file without any problems, but the cannot.
I have tried to scrap the project settings window for a xcconfig setup instead, so may have done something wrong there. Any ideas as to what I am missing?
Note that paths such as /usr/lib are prefixed by your SDK setting, so what you think is /usr/lib may in fact be e.g. /Developer/SDKs/MacOSX10.6.sdk/usr/lib (if your SDK is set to 10.6).
If you want to link to something in /usr/lib and not in /Developer/SDKs/bla/usr/lib you'll need to use full path to the library when linking. Add it to "Other Linker Flags": /usr/lib/somelib.dylib (note that there is no -l in front of the path)

Resources