Executable links correctly but fails to load a library - cmake

I have Boost and Served REST API package installed in /opt/local.
Here's the "meaningful" part of my CmakeLists.txt:
find_package(PkgConfig REQUIRED)
pkg_check_modules(SERVED_PKG REQUIRED IMPORTED_TARGET served)
add_executable( rest_server rest_server.cpp )
target_link_libraries(rest_server PUBLIC PkgConfig::SERVED_PKG)
It does create an executable, and links it with the needed library.
However, it somehow fails to include the path to that library:
$ otool -L cmake-build-debug/rest_server
cmake-build-debug/rest_server:
libserved.1.4.dylib (compatibility version 0.0.0, current version 1.4.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 902.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1)
Which, when I try to run it via the CLion IDE, results in a failure to load the libserved.1.4.dylib library:
/Users/ur20980/src/security2/cmake-build-debug/rest_server
dyld: Library not loaded: libserved.1.4.dylib
Referenced from: /Users/ur20980/src/security2/cmake-build-debug/rest_server
Reason: image not found
Process finished with exit code 6
When I invoke the executable manually from the terminal, it seems to be OK:
$ cmake-build-debug/rest_server
Hello, World!
What is wrong???

Related

Packaged build environment as build_requires of profiles, system compiler is used instead

I will try to describe my setup first:
conan 1.29.2
Official cmake/3.18.2 package
Custom gcc package with package_info including its bin directory in PATH and setting the CC and CXX env variables:
def package(self):
autotools = AutoToolsBuildEnvironment(self)
autotools.make(target='install-strip')
def package_info(self):
bin_folder = os.path.join(self.package_folder, 'bin')
self.env_info.path.append(bin_folder)
self.env_info.CXX = os.path.join(bin_folder, 'g++')
self.env_info.CC = os.path.join(bin_folder, 'gcc')
linux-x86_64 conan profile representing Linux 64 bit environment as follows:
[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
linux-x86_64-Debug conan profile representing Linux 64 bit Release environment as follows:
include(linux-x86_64)
[settings]
build_type=Debug
gcc-10.1.0 conan profile to build packages using my gcc package:
[settings]
compiler=gcc
compiler.version=10.1
compiler.libcxx=libstdc++11
[build_requires]
gcc/10.1.0
cmake-3.18.2 conan profile to build packages using official cmake package:
[build_requires]
cmake/3.18.2
default conan profile with gcc 7
If I try to build a package as follows:
$ conan create . foo/version --build=missing -pr linux-x86_64-Debug -pr cmake-3.18.2 -pr gcc-10.1.0
the resulting config is:
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Debug
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=10.1
os=Linux
os_build=Linux
[options]
[build_requires]
*: gcc/10.1.0, cmake/3.18.2
[env]
which looks right to me...
and then conan starts building cmake package for the gcc 10.1 x86_64 config:
cmake/3.18.2: WARN: Build folder is dirty, removing it: /home/manuel/.conan/data/cmake/3.18.2/_/_/build/46c0026dddc0e0537a797652343e8e1e9d0e39e7
cmake/3.18.2: Copying sources to build folder
cmake/3.18.2: Building your package in /home/manuel/.conan/data/cmake/3.18.2/_/_/build/46c0026dddc0e0537a797652343e8e1e9d0e39e7
cmake/3.18.2: Generator cmake created conanbuildinfo.cmake
cmake/3.18.2: Calling build()
But then build fails because the cmake package cmake config is using the system compiler:
-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is GNU 7.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Conan: called by CMake conan helper
-- Conan: called inside local cache
-- Conan: Adjusting output directories
-- Conan: Using cmake global configuration
-- Conan: Adjusting default RPATHs Conan policies
-- Conan: Adjusting language standard
-- Conan: Compiler GCC>=5, checking major version 10.1
-- Conan: Checking correct version: 7.4
CMake Error at ../conanbuildinfo.cmake:510 (message):
Detected a mismatch for the compiler version between your conan profile
settings and CMake:
Compiler version specified in your conan profile: 10.1
Compiler version detected in CMake: 7.4
Please check your conan profile settings (conan profile show
[default|your_profile_name])
P.S. You may set CONAN_DISABLE_CHECK_COMPILER CMake variable in order to
disable this check.
Call Stack (most recent call first):
../conanbuildinfo.cmake:592 (conan_error_compiler_version)
../conanbuildinfo.cmake:695 (check_compiler_version)
../conanbuildinfo.cmake:249 (conan_check_compiler)
CMakeLists.txt:9 (conan_basic_setup)
This looks very similar to https://github.com/conan-io/conan/issues/1842, but that issue is from 3 years ago.
Conan learned some versions ago about host and build contexts and is able to manage different configurations for those contexts. This is preferred over the old os_build and arch_build settings and packages in ConanCenter are moving towards this new feature.
In your scenario, you are trying to build a library using packages gcc and cmake as build-requires. You are building library for the host machine and using package gcc and cmake that provide tools that should run in the build machine. Even if you are not cross-compiling, we can agree that native building is just a specific use-case where host and build are the same machine and, hence, they use the same Conan configuration.
Back to your example. You need your profiles for the host platform, the one you want to generate your library for. These are all the profiles you have listed in your question. But you also need a profile for the build context, the profile that Conan will use to build (or retrieve) the gcc and cmake packages. For example, you might want to use a profile linux-x86_64-Debug to compile your library in debug mode, while using gcc and cmake in Release.
Typically, the profile for your build context can be the default profile detected by Conan.
Try this command instead of yours (note the --profile:build=default):
conan create <library/conanfile.py> foo/version --build=missing --profile:host linux-x86_64-Debug --profile:host cmake-3.18.2 --profile:host gcc-10.1.0 --profile:build=default
Now Conan will use the new feature and assign the package to the corresponding contexts:
library and all its dependencies will be assigned to the host context and will use information from all the --profile:host profiles: your Debug build and Conan will add cmake and gcc as build-requires.
gcc and cmake, as they are build-requires in this command, will be assigned to the build context and will use the information from the --profile:build. If Conan needs to build these packages it will use the settings from that profile, not the settings for the host profiles.
With this setup you can build all packages in a cross-building scenario in a single run: packages in the host context will use your build-requires gcc to build, while packages in the build context will use the tools defined in the --profile:build.
Yes, in this scenario, packages in the build context will use the compiler from your system.... unless you declare [build_requires] inside the --profile:build.

Use LLVM in a cmake build

I'm trying to build my own project that use LLVM. I downloaded the source code and the precompiled package on the official web site (last version).
http://releases.llvm.org/download.html
I downloaded :
LLVM source code
Clang for Windows (64-bit)
FYI, I don't build LLVM... only want to use it !
I followed the instruction here :
http://llvm.org/docs/CMake.html#embedding-llvm-in-your-project
in the section : "Embedding LLVM in your project"
So, I added this code :
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
message("LLVM_INCLUDE_DIRS=${LLVM_INCLUDE_DIRS}")
message("LLVM_DEFINITIONS=${LLVM_DEFINITIONS}")
But I got several cmake error messages, here is my output :
-- Using LLVMConfig.cmake in: C:\\Luciad_src\\libs\\LLVM\\cmake\\modules
LLVM_INCLUDE_DIRS=
LLVM_DEFINITIONS=
CMake Error at C:/Luciad_src/libs/LLVM/cmake/modules/LLVM-Config.cmake:31 (list):
list sub-command REMOVE_ITEM requires two or more arguments.
Call Stack (most recent call first):
C:/Luciad_src/libs/LLVM/cmake/modules/LLVM-Config.cmake:256 (is_llvm_target_library)
components/query/CMakeLists.txt:15 (llvm_map_components_to_libnames)
Is there a problem with my script, or the packages I use ? Any idea ?
Thanks for your help
You can have the LLVM as binary or source package.
The binary package does not include CMake support. If you compare both installations (binary on the left, source after building and installing it on the right) you can see the difference:
LLVM-5.0.0-win64.exe
<=> llvm-5.0.1.src.tar.xz (build and installed)
So you need to build and install the source package first to get CMake support. On my Windows machine I needed a cmd shell with administrator rights, a Visual Studio installation, go to the downloaded and extracted sources and do:
> mkdir mybuilddir
> cd mybuilddir
> cmake ..
> cmake --build . --config Release --target INSTALL
If I now use your CMake example I get:
-- Found LLVM 5.0.1
-- Using LLVMConfig.cmake in: C:/Program Files (x86)/LLVM/lib/cmake/llvm
LLVM_INCLUDE_DIRS=C:/Program Files (x86)/LLVM/include
LLVM_DEFINITIONS=-DLLVM_BUILD_GLOBAL_ISEL -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -DUNICODE -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-- Configuring done

cross compile azure iot sdk

I try to crosscompile the Azure IoT C SDK (https://github.com/azure/azure-iot-sdk-c) for a BeagleBoard Black.
I did setup a Debian GNU/Linux 8.7 (jessie) Machine and installed the toolchain as described here: http://exploringbeaglebone.com/chapter7/.
Then i followed the steps here:
https://github.com/Azure/azure-iot-sdk-c/blob/master/doc/SDK_cross_compile_example.md and Created a Toolchain file:
INCLUDE(CMakeForceCompiler)
SET(CMAKE_SYSTEM_NAME Linux) # this one is important
SET(CMAKE_SYSTEM_VERSION 1) # this one not so much
# this is the location of the amd64 toolchain targeting the Raspberry Pi
SET(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_FIND_ROOT_PATH /usr/lib/arm-linux-gnueabihf)
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
i call the Buildscript of the azure-sdk using:
./build.sh --toolchain-file toolchain-bb.cmake -cl --sysroot=/usr/lib/arm-linux-gnueabihf
The following Error Occures
CMake Error at /usr/share/cmake-3.0/Modules/FindPackageHandleStandardArgs.cmake:136 (message):
Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
system variable OPENSSL_ROOT_DIR (missing: OPENSSL_LIBRARIES
OPENSSL_INCLUDE_DIR)
Call Stack (most recent call first):
/usr/share/cmake-3.0/Modules/FindPackageHandleStandardArgs.cmake:343 (_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake-3.0/Modules/FindOpenSSL.cmake:328 (find_package_handle_standard_args)
c-utility/CMakeLists.txt:141 (find_package)
i tried to install openssl using:
sudo apt-get install openssl:armhf
but the error remains, if i build the source for arm64 (using just the build.sh file of the azure-iot-sdk) everything works fine.
if i clone openssl and build it targeting arm i get the following error:
CMake Error at /usr/share/cmake-3.0/Modules/FindPackageHandleStandardArgs.cmake:136 (message):
Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
system variable OPENSSL_ROOT_DIR (missing: OPENSSL_LIBRARIES) (found
version "1.1.1")
If you have Openssl present in your tool chain then you simply need to add a couple of additional lines to your cmake toolchain file. This will help cmake find your libraries and headers. Something like this:
SET(OPENSSL_ROOT_DIR /path/to/openssl/lib)
SET(OPENSSL_INCLUDE_DIR /path/to/openssl/include/)
If it is not present then you will need to cross compile openssl for your target and install it into your toolchain. Typically into /<sysroot>/usr/lib and /<sysroot>/usr/include.
Alternatively if openssl is on your device but not in your toolchain then you can simply copy it from the device. There is an example of copying dependencies to the toolchain in the Raspberry Pi demo here: https://github.com/Azure/azure-iot-sdk-c/blob/master/doc/SDK_cross_compile_example.md

CMake does not link glfw right under osx

20160614:
I have glfw installed by MacPorts.
sudo port install glfw
And I have checked that /opt/local/lib/libglfw.dylib is exists.
Here is my top header of main.cpp:
#include <GLFW/glfw3.h>
My CMakeLists.txt(file1):
cmake_minimum_required (VERSION 2.8)
project (t1)
include_directories(/opt/local/include)
link_directories(/opt/local/lib)
# find_library(MYGLFWLIB NAMES glfw HINTS /opt/local/lib NO_DEFAULT_PATH)
set(GLLIBS GL glfw glew)
add_executable(t1 main.cpp)
target_link_libraries(t1 ${GLLIBS})
After cmake . && make which is no error reported, I execute by ./t1
Then Error came:
dyld: Library not loaded: lib/libglfw.3.dylib
Referenced from: /Users/...../t1
Reason: image not found
[1] 13949 trace trap ./t1
Then I use otool -L t1 to check lib dependens in t1
/opt/local/lib/libGL.1.dylib (compatibility version 4.0.0, current version 4.0.0)
lib/libglfw.3.dylib (compatibility version 3.0.0, current version 3.2.0)
/opt/local/lib/libGLEW.1.13.0.dylib (compatibility version 1.13.0, current version 1.13.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
Could someone tell me why glfw is not linked rightly?
20160615:
After modifying my CMakeLists.txt(file2):
cmake_minimum_required (VERSION 2.8)
project (t1)
include_directories(/opt/local/include)
link_directories(/opt/local/lib)
find_library(GL_LIB GL HINTS /opt/local/lib )
find_library(GLFW_LIB glfw HINTS /opt/local/lib)
find_library(GLEW_LIB glew HINTS /opt/local/lib)
message(${GLFW_LIB})
message(${GLEW_LIB})
message(${GL_LIB})
add_executable(t1 main.cpp)
target_link_libraries(t1 ${GL_LIB} ${GLFW_LIB} ${GLEW_LIB})
I have two osx device(MacMini and MacBookPro), the version of MacPorts and Xcode and CMake and System are all the same:
Mac osx : 10.11.5
MacPorts 2.3.4
CMake :3.5.2
Xcode: 7.3
Both version of CMakeLists (file1 and file2 above)works in MacMini, linker works fine.
But when it cames to my MacBookPro, glfw is not linked well.
Someone else had encounter the almost same problem:
macports-cmake-make-dyld-library-not-loaded
Is this problem SYSTEM VARIABLE concerned ?
After search for hours, I found the reason : glfw #3.2: install_name is not set properly
set(GLLIBS GL glfw glew)
That's not how you should use CMake. Use find_library or
pkg_search_module(GLFW REQUIRED glfw3)
include_directories(${GLFW_INCLUDE_DIRS})
target_link_libraries(simple ${GLFW_LIBRARIES})
Have a look into the documentation:
http://www.glfw.org/docs/3.0/build.html

Trouble when linking Objective-C program with my own libobjc.A.dylib

I builded a custom libobjc.A.dylib from the source of apple's open source website and I want to debug it by compiling a simple program with the dylib, but it seems the clang always using the system libobjc.A.dylib.
The compile command is:
xcrun --sdk macosx10.8 clang main.m -std=c99 -framework Foundation -lobjc -I./usr/include -L.
the libobjc.A.dylib is in the current folder. And the otool command tells me which library the program links with:
~ otool -L a.out
a.out:
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 945.18.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 744.19.0)
In the http://opensource.apple.com/source/objc4/objc4-551.1/test/test.pl file, it's using a flag called -fno-objc-link-runtime, but it seems it's not working with my laptop(mac 10.9.4, xcode 5.1.1)
Tried setting DYLD_LIBRARY_PATH environment var, but it's not working. Here is the folder which I compiled the code https://github.com/Jeswang/Compile-Issue, any suggestion or solution?
Actually, I used install_name_tool command to change the library's link:
install_name_tool -change /usr/lib/libobjc.A.dylib #executable_path/libobjc.A.dylib main
Useful links:
dyld manual
mikeash.com: Friday Q&A 2009-11-06: Linking and Install Names