CMake INSTALL and RENAME cannot find file - cmake

I'm trying to make and install a config.cmake file for the project that I'm building, and the install part isn't working because apparently it can't find the file. I was originally using the INSTALL command from cmake, and when that didn't work I tried file( RENAME ... ) because I have a little more experience with it - neither seem to work. I've verified that the file is being made in the correct location and with the expected filename.
This is the relevant part of the CMakeLists.txt:
################################################################################
# Build the config.cmake file for finding project information
################################################################################
file(WRITE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake "set(${PROJECT_NAME}_PROTO_DIR ${PROTO_MAIN_DIR})\n")
file(APPEND ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake "set(${PROJECT_NAME}_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/include/;${PROTO_GEN_DIR})\n")
file(APPEND ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake "set(${PROJECT_NAME}_LIBRARY_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/)\n")
file(APPEND ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake "set(${PROJECT_NAME}_LIBRARIES ${PROJECT_LIBRARIES})\n")
message( "CMAKE_BINARY_DIR: " ${CMAKE_BINARY_DIR} )
message( "PROJECT_NAME: " ${PROJECT_NAME} )
#INSTALL(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake DESTINATION ~/CMake/Modules/)
file(RENAME ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake ~/CMake/Modules/${PROJECT_NAME}Config.cmake)
Here's the relevant output when I try to rune cmake:
CMAKE_BINARY_DIR: /home/ava/workspace/frontseat_drivers/build
PROJECT_NAME: frontseat
CMake Error at src/frontseat/CMakeLists.txt:47 (file):
file RENAME failed to rename
/home/ava/workspace/frontseat_drivers/build/frontseatConfig.cmake
to
~/CMake/Modules/frontseatConfig.cmake
because: No such file or directory
and here's output confirming that the file is where I expect with the name that I expect:
ava#3b97b310abf0:~/workspace/frontseat_drivers/build$ ls -l
total 32
-rw-rw-r--. 1 ava ava 12219 Jun 13 19:04 CMakeCache.txt
drwxrwxr-x. 5 ava ava 4096 Jun 13 18:48 CMakeFiles
-rw-rw-r--. 1 ava ava 2250 Jun 13 15:41 cmake_install.cmake
-rw-rw-r--. 1 ava ava 315 Jun 14 12:30 frontseatConfig.cmake
-rw-rw-r--. 1 ava ava 6397 Jun 13 18:48 Makefile
drwxrwxr-x. 5 ava ava 98 Jun 13 18:48 src
What would cause CMake not to be able to see the file?

The error is probably about destination file ~/CMake/Modules/frontseatConfig.cmake. It is because CMake doesn't interpret ~ part, so it cannot resolve the path correctly.
Instead of ~ use $ENV{HOME} for point to the user's home directory.

Related

Can not link libuuid when using CMake toolchain file to cross-compile Azure IoTHub SDK

I don't know how to write CMake toolchain-file properly to build Azure IoTHub SDK v1.2.10 successfully.
This is my command:
azure-iot-sdk-c/build_all/linux# ./build.sh --no-amqp --no-http --no_uploadtoblob --no-logging --toolchain-file mytoolchain.cmake
And here is the build result, ld cannot find -luuid:
Scanning dependencies of target iothub_convenience_sample
[ 69%] Building C object iothub_client/samples/iothub_convenience_sample/CMakeFiles/iothub_convenience_sample.dir/iothub_convenience_sample.c.o
[ 70%] Building C object iothub_client/samples/iothub_convenience_sample/CMakeFiles/iothub_convenience_sample.dir/__/__/__/certs/certs.c.o
[ 71%] Linking C executable iothub_convenience_sample
/usr/local/bin/compile_tool/arm-2010q1/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/../../../../arm-none-linux-gnueabi/bin/ld: cannot find -luuid
collect2: ld returned 1 exit status
iothub_client/samples/iothub_convenience_sample/CMakeFiles/iothub_convenience_sample.dir/build.make:128: recipe for target 'iothub_client/samples/iothub_convenience_sample/iothub_convenience_sample' failed
make[2]: *** [iothub_client/samples/iothub_convenience_sample/iothub_convenience_sample] Error 1
CMakeFiles/Makefile2:1327: recipe for target 'iothub_client/samples/iothub_convenience_sample/CMakeFiles/iothub_convenience_sample.dir/all' failed
make[1]: *** [iothub_client/samples/iothub_convenience_sample/CMakeFiles/iothub_convenience_sample.dir/all] Error 2
Makefile:140: recipe for target 'all' failed
make: *** [all] Error 2
Below is my toolchain-file:
INCLUDE(CMakeForceCompiler)
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER /usr/local/bin/compile_tool/arm-2010q1/bin/arm-none-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER /usr/local/bin/compile_tool/arm-2010q1/bin/arm-none-linux-gnueabi-g++)
# set OpenSSL path
SET(OPENSSL_SSL_LIBRARY /myspace/application/openssl/libssl.so)
SET(OPENSSL_CRYPTO_LIBRARY /myspace/application/openssl/libcrypto.so)
SET(OPENSSL_INCLUDE_DIR /myspace/application/openssl/include)
# I can use INCLUDE_DIRECTORIES to find uuid.h
INCLUDE_DIRECTORIES(/myspace/application/libuuid/include)
# But I can't link libuuid by setting CMAKE_FIND_ROOT_PATH... Why?
SET(CMAKE_FIND_ROOT_PATH /myspace/application/libuuid/lib)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
I've downloaded libuuid sources and built it into /myspace/application/libuuid/lib/:
root#my-pc:/myspace/application/libuuid/lib# ls -l
total 116
-rw-r--r-- 1 root root 63258 十一 9 13:57 libuuid.a
-rwxr-xr-x 1 root root 953 十一 9 13:57 libuuid.la
lrwxrwxrwx 1 root root 16 十一 9 13:57 libuuid.so -> libuuid.so.1.0.0
lrwxrwxrwx 1 root root 16 十一 9 13:57 libuuid.so.1 -> libuuid.so.1.0.0
-rwxr-xr-x 1 root root 41893 十一 9 13:57 libuuid.so.1.0.0
drwxr-xr-x 2 root root 4096 十一 9 13:57 pkgconfig
However, if I manually copy libuuid.so.1 and libuuid.so.1.0.0 to the path within my cross-compiler(/usr/local/bin/compile_tool/arm-2010q1/arm-none-linux-gnueabi/lib), it can successfully link libuuid.
So, I think there must be something wrong in my toolchain-file. I've tried to use CMAKE_EXE_LINKER_FLAGS, CMAKE_SHARED_LINKER_FLAGS, link_directories, and link_libraries, all of above failed.
I hope somebody can teach me how to improve my toolchain-file. Thanks!
PS. I don't want to modify Azure IoTHub sources in order to keep it unchanged and easy to maintain.
I have installed compiled libuuid library in cross compiler default path. I use aarch64-linux-gnu so default path will be /usr/aarch64-linux-gnu/

CMake define new target by string processing existing $<TARGET_FILE>

I"m trying to modernize an older CMake script that essentially does the following to generate a libtool file:
get_target_property(target_location ${target} LOCATION)
get_filename_component(target_we ${target_location} NAME_WE)
get_target_property(target_deps ${target} LT_DEPENDENCY_LIBS)
# ...
# Get a bunch more properties...
# ...
set(la_target ${PROJECT_BINARY_DIR}/${target_we}.la)
# ...
# Do a bunch of file(WRITE...) file(APPEND...) etc
# ...
install(FILES ${la_target} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
You cannot get the LOCATION property from a target in modern cmake, and I can't figure out how to do get_filename_component() on a $ generator.
Using the generator in an add_custom_command() COMMAND statement only allows one line, so I can't set variables to do all the necessary get_target_property()/file(WRITE...) processing.
Alternatively I can add a COMMAND cmake -P script.cmake to run a script which can do all the string processing but can't define or reference targets, so I appear to be stuck.
EDIT: I'm using the Makefile generator, on macOS, the target in question is a shared library that's generated in the same project.
EDIT2: The error is:
The LOCATION property may not be read from target "mytarget".
Use the target name directly with add_custom_command, or use
the generator expression $<TARGET_FILE>, as appropriate.
You can to it like this:
first use file command to expand generator expressions and render a level-2 template
... which is going to be rendered at build time by configure_file
Here is a sample project:
cmake_minimum_required(VERSION 3.10)
project(location-test VERSION 0.0.1 LANGUAGES CXX)
add_executable(foo foo.cc)
file(GENERATE OUTPUT blah.la.in INPUT blah.la.in.in)
configure_file(render-variables.cmake.in render-variables.cmake #ONLY)
add_custom_command(
OUTPUT "${PROJECT_BINARY_DIR}/blah.la"
COMMAND "${CMAKE_COMMAND}"
-DPROJECT_BINARY_DIR="${PROJECT_BINARY_DIR}"
-DPROJECT_NAME="${PROJECT_NAME}"
-DPROJECT_VERSION="${PROJECT_VERSION}"
-P "${PROJECT_BINARY_DIR}/render-variables.cmake"
MAIN_DEPENDENCY "${PROJECT_BINARY_DIR}/blah.la.in"
DEPENDS "${PROJECT_BINARY_DIR}/render-variables.cmake"
)
add_custom_target(
make-la-la-la ALL
DEPENDS "${PROJECT_BINARY_DIR}/blah.la"
)
blah.la.in.in (2-levels of tempaltes %):
# This file going to be rendered by the following pipeline:
# - at CMake execution time it'll expand all generator expressions
# (e.g. $<TARGET_FILE:foo>)
# - at build time, the `render-variables.cmake` script will substitute
# CMake variables (like #PROJECT_NAME# or #PROJECT_VERSION#)
write the template for your real .la file... render-variables.cmake.in is trivial as :
configure_file("${PROJECT_BINARY_DIR}/blah.la.in" "${PROJECT_BINARY_DIR}/blah.la" #ONLY)
And finally a dummy C++ file foo.cc:
#include <iostream>
int main()
{
std::cout << "Hello Africa!\n";
}
Build it!
localtion-sample$ mkdir build/
localtion-sample$ cd build/
localtion-sample/build$ cmake ..
-- The CXX compiler identification is GNU 5.4.0
-- Check for working CXX compiler: /usr/x86_64-pc-linux-gnu/gcc-bin/5.4.0/c++ -- works
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/localtion-sample/build
localtion-sample/build$ make
Scanning dependencies of target foo
[ 33%] Building CXX object CMakeFiles/foo.dir/foo.cc.o
[ 66%] Linking CXX executable foo
[ 66%] Built target foo
Scanning dependencies of target make-la-la-la
[100%] Generating blah.la
[100%] Built target make-la-la-la
localtion-sample/build$ ll
total 52K
drwxr-xr-x 6 zaufi zaufi 320 Feb 9 22:35 CMakeFiles/
-rw-r--r-- 1 zaufi zaufi 287 Feb 9 22:35 blah.la
-rw-r--r-- 1 zaufi zaufi 300 Feb 9 22:35 blah.la.in
-rw-r--r-- 1 zaufi zaufi 11K Feb 9 22:35 CMakeCache.txt
-rw-r--r-- 1 zaufi zaufi 1.5K Feb 9 22:35 cmake_install.cmake
-rwxr-xr-x 1 zaufi zaufi 14K Feb 9 22:35 foo
-rw-r--r-- 1 zaufi zaufi 5.0K Feb 9 22:35 Makefile
-rw-r--r-- 1 zaufi zaufi 89 Feb 9 22:35 render-variables.cmake
localtion-sample/build$ cat blah.la
# This file going to be rendered by the following pipeline:
# - at CMake execution time it'll expand all generator expressions
# (e.g. /tmp/localtion-sample/build/foo)
# - at build time, the `render-variables.cmake` script will substitute
# CMake variables (like location-test or 0.0.1)

CMake shared library executable permission missing at install location

Currently I am creating a simple project which will install a utility shared library.
Here's my CMakeLists:
cmake_minimum_required (VERSION 2.6)
project(MathLibs CXX)
add_library (${PROJECT_NAME} SHARED
fact.cpp
fibo.cpp
isPrime.cpp
)
install (TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${PROJECT_NAME}/bin
LIBRARY DESTINATION ${PROJECT_NAME}/lib
ARCHIVE DESTINATION ${PROJECT_NAME}/lib)
Since I do not have root privileges I cannot install the shared library in system lib folder. I override the CMAKE_INSTALL_PREFIX to $HOME/apps.
When I build the shared library it had the executable permissions.
Here's the build folder with the shared library:
-rw-rw-r-- 1 ameya ameya 9714 Jun 18 20:02 CMakeCache.txt
drwxrwxr-x 5 ameya ameya 4096 Jun 18 20:02 CMakeFiles
-rw-rw-r-- 1 ameya ameya 2701 Jun 18 20:02 cmake_install.cmake
-rw-rw-r-- 1 ameya ameya 84 Jun 18 20:02 install_manifest.txt
-rwxrwxr-x 1 ameya ameya 6808 Jun 18 20:02 libMathLibs.so
-rw-rw-r-- 1 ameya ameya 7748 Jun 18 20:02 Makefile
drwxrwxr-x 3 ameya ameya 4096 Jun 18 20:02 test
After installing the executable permissions disappears.
Here's the install folder location:
-rw-r--r-- 1 ameya ameya 6808 Jun 18 20:02 libMathLibs.so
What am I missing in the CMakeLists.txt to correct this?
They said that CMake doesn't set execute permissions on installed library because on Linux libraries don't need to be executable.
As for library's permissions in build tree, these are set not by CMake but by the linker.
If you want executable permissions of installed library for some reason, use PERMISSIONS option in install() command.
After looking for more details online I found this referenced in the CMake bugs report.
The handling of shared library on different systems is different I tried using Ubuntu and a Fedora workstation.
On Ubuntu system the system installed shared libraries do not have the executable bit set, but on the Fedora Workstation the same library had the executable bit set.
One can have look at the ${CMAKE_ROOT}/cmake/Modules/Platform/Linux.cmake,
which has the CMAKE_INSTALL_SO_NO_EXE macro defined(sorry for the typo in my earlier reply).

LLVm clang , Error: Invalid file format (bad magic) with -fprofile-instr-use

Flag "-fprofile-instr-use" generates error given below.
This issue occurs even if we build llvm,clang and compiler-rt using cmake or configure.
Please let me know your inputs to resolve this issue
error: Could not read profile: Invalid file format (bad magic)
Thanks,
Steps to reproduce this issue:
$ clang -O2 -fprofile-instr-generate hello.c -o c1.out
$ ls -rlt
-rw-r--r-- 1 root root 70 Jul 11 10:10 hello.c
-rwxr-xr-x 1 root root 15793 Jul 11 10:10 c1.out
-rw-r--r-- 1 root root 12203204 Jul 11 10:10 gmon.out
$ ./c1.out
Hello world
$ ls -rlt
-rw-r--r-- 1 root root 70 Jul 11 10:10 hello.c
-rwxr-xr-x 1 root root 15793 Jul 11 10:10 c1.out
-rw-r--r-- 1 root root 12203204 Jul 11 10:10 gmon.out
-rw-r--r-- 1 root root 104 Jul 11 10:10 default.profraw
$ clang -O2 -fprofile-instr-use=default.profraw hello.c -o c2.out
error: Could not read profile: Invalid file format (bad magic)
1 error generated.
Clang version (July 10th-2014 build from stage):
$ clang -v
clang version 3.5.0 (llvm.org/git/clang.git 5f9d646cba20f309bb69c6c358996d71912c54cd) (llvm.org/git/llvm.git dc90a3ab8ffc841a442888940635306de6131d2f)
Target: x86_64-unknown-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.2
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.0
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8
Candidate multilib: .;#m64
Candidate multilib: 32;#m32
Selected multilib: .;#m64
OS: Ubuntu 14.04
LLVM configure: ../llvm/configure --enable-profiling --enable-optimized --enable-shared --disable-debug-runtime --enable-targets=x86
It turns out that step 3 outlined here: http://clang.llvm.org/docs/UsersManual.html#profiling-with-instrumentation
is required even if you only have 1 output file you are using. "Combine profiles from multiple runs and convert the “raw” profile format to the input expected by clang" makes it sound like you should only do this if you have multiple profiles, but you need to do it unconditionally.

Cmake/cpack: how to create a libc++ static library deb without headers?

I have been trying to create a deb for LLVM libc++ 3.4 on a Ubuntu 12.04LTS 64bit box tonight. I would like to first create a deb that just consists of just /usr/lib64/libc++.a without any headers. Yes, I know per Debian library packaging guide, I should include the file in a *-dev package, But being new to cmake and cpack, I would like to get there incrementally.
So, I first changed the libcxx-3.4/lib/CMakeLists.txt and added an if check (see line 14 and 18)
$ cat CMakeLists.txt
1 if (NOT LIBCXX_INSTALL_SUPPORT_HEADERS)
2 set(LIBCXX_SUPPORT_HEADER_PATTERN PATTERN "support" EXCLUDE)
3 endif()
4
5 file(COPY .
6 DESTINATION "${CMAKE_BINARY_DIR}/include/c++/v1"
7 FILES_MATCHING
8 PATTERN "*"
9 PATTERN "CMakeLists.txt" EXCLUDE
10 PATTERN ".svn" EXCLUDE
11 ${LIBCXX_SUPPORT_HEADER_PATTERN}
12 )
13
14 if (${LIBCXX_ENABLE_SHARED} MATCHES "ON")
15 install(DIRECTORY "${CMAKE_BINARY_DIR}/include/c++/v1/"
16 DESTINATION include/c++/v1/
17 )
18 endif()
Then, at in the build subdirectory, I issued a
CC=clang CXX=clang++ cmake -j2 -G "Unix Makefiles" -DLIBCXX_CXX_ABI=libcxxabi -DLIBCXX_LIBCXXABI_INCLUDE_PATHS="../libcxxabi/include" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr ../libcxx -DLIBCXX_ENABLE_SHARED=OFF
The created deb still consists of all headers. If I commented out lines 14 to 18, then no headers were included in the package. I am puzzled by this. A variable defined for the parent CMakeLists.txt should be picked up by a child CMakeLists.txt. What did I miss? I would appreciate a hint or two.
I have figured out the answer for my own question. Being new to cmake and cpack, I initially focused on the wrong CMakeLists.txt. The install command for headers in the include/CMakeLists.txt is not the only one. The main CMakeLists.txt file has a marcro in which there is also an install command. That should be disabled too. Specifically:
In the main CMakeLists.txt, one could do:
129 message(STATUS "Inside of setup_abi_libs; LIBCXX_ENABLE_SHARED: ${LIBCXX_ENABLE_SHARED}")
130 if (LIBCXX_ENABLE_SHARED)
131 install(DIRECTORY "${CMAKE_BINARY_DIR}/include/"
132 DESTINATION include/c++/v1
133 FILES_MATCHING
134 PATTERN "*"
135 )
136 endif()
137 endmacro()
Then, in the include/CMakeLists.txt, one could do:
13
14 message(STATUS "Inside of include; LIBCXX_ENABLE_SHARED: ${LIBCXX_ENABLE_SHARED}")
15
16 if (LIBCXX_ENABLE_SHARED)
17 install(DIRECTORY "${CMAKE_BINARY_DIR}/include/c++/v1/"
18 DESTINATION include/c++/v1/
19 )
20 endif()
This is the end result that I was trying to obtain but failed last night:
$ dpkg-deb -c libcxx_3.4-1_amd64.deb
drwxrwxr-x root/root 0 2014-03-04 08:59 ./usr/
drwxrwxr-x root/root 0 2014-03-04 08:59 ./usr/lib64/
-rw-r--r-- root/root 1928770 2014-03-04 08:58 ./usr/lib64/libc++.a
No more headers. Now I just need to figure out how to change the original CMakeLists.txt files to make a real dev package :)
Please read documenation for if:
MATCHES is for regular expressions, use if (LIBCXX_ENABLE_SHARED) or if (${LIBCXX_ENABLE_SHARED} STREQUAL "ON") instead