CMake RUNTIME_OUTPUT_DIRECTORY not considerered - cmake

I am trying to import vector_blf into a project with FetchContent_Declare() like this:
FetchContent_Declare(
vector_blf
GIT_REPOSITORY https://github.com/Technica-Engineering/vector_blf.git
GIT_TAG 02f0a2fe1f7915da1e24025869b98f6d15de937b
)
FetchContent_MakeAvailable(vector_blf)
target_link_libraries(labplot2lib Vector_BLF)
.
.
.
add_executable( labplot2 ${LABPLOT_SOURCE} ${qml_QRC} )
target_link_libraries( labplot2 labplot2lib )
install( TARGETS labplot2 ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
with KDE_INSTALL_TARGETS_DEFAULT_ARGS
RUNTIMEDESTINATIONbinLIBRARYDESTINATIONlibARCHIVEDESTINATIONlibCOMPONENTDevelINCLUDESDESTINATIONinclude
this works fine and it builds on windows and linux. The library of vector_blf target is installed to lib which is fine on linux, but on windows it needs to be in bin. But it will not be considered even with RUNTIME DESTINATION to bin.
in the vector_blf project they are using GnuInstallDirs and
install(
TARGETS ${PROJECT_NAME}
DESTINATION ${CMAKE_INSTALL_LIBDIR})
to install the library.
I tried to overwrite the RUNTIME_OUTPUT_DIRECTORY of Vector_BLF with set_target_properties but with no success.
What is the proper way to install the library to the bin folder?

Related

Using cmake.js with google test for testing a node.js addon

I am trying to test a node-js addon (built with cmake-js) with google test.
I am building on Mac OS.
The addon target builds and runs ok, but I have problems with the googletest target.
I am getting linking errors related to undefined V8 methods.
In CMakeLists.txt I printed (with message) the variables CMAKE_JS_SRC and CMAKE_JS_LIB and they are both empty. If CMAKE_JS_LIB is empty I don't see how target_link_libraries() should work to add the node/v8 library to my test executable...
If instead of using add_executable() I use add_library() the google_test target builds but of course I can not run it since it is not an executable anymore.
Can you help?
Below is my CMakeLists.txt:
make_minimum_required(VERSION 3.14)
include_directories(my_project)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_C_FLAGS "-Wno-pointer-sign -fno-signed-char -std=c99 -fpermissive")
set(CMAKE_CXX_FLAGS "-Wno-pointer-sign -fno-signed-char -std=c99 -fpermissive")
project (addon)
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.12.1
)
FetchContent_MakeAvailable(googletest)
include_directories(${CMAKE_JS_INC} "my_project/include/pkcs11/v2.40/")
file(GLOB SOURCE_FILES "my_project/*.c" "my_project/*.h" "my_project/*.cpp")
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB} )
## google_test
enable_testing()
file(GLOB TEST_FILES "test/*.cc" "test/utils/*.c")
add_executable(
my_project_google_test
${TEST_FILES)
)
target_include_directories(my_project_google_test
PRIVATE
test/utils/*.h
)
target_link_libraries(
my_project_google_test
PRIVATE
GTest::gtest_main
${CMAKE_JS_LIB}
)
include(GoogleTest)
gtest_discover_tests(my_project_google_test)
CMAKE_JS_LIB is empty everywhere except on Windows.
Install v8 from Homebrew if you haven't done it yet: brew install v8.
Link the app to v8
target_link_libraries(
my_project_google_test
PRIVATE
v8
)
Other v8 libraries can be required, you have not post all errors: v8_libbase v8_libplatform.

Setting up a cmake project properly with thirdparty

I am trying to get better on CMake. Currently I try to build a toy example that is using OpenCV that I have built from source and installed in a directory called thirdparty.
I can run build
cmake ..
cmake --build .
cmake --install . --prefix ../tmp
In build I can run ./app/TestOpenCV and get a 3x4 zero matrix as output.
If I run ../tmp/bin/TestOpenCV I get
Reason: tried: '/usr/local/lib/libopencv_gapi.406.dylib' (no such file), '/usr/lib/libopencv_gapi.406.dylib' (no such file)
It appears that the linking is not working appropriately when I install the binary. I.e. it searching for the libraries in the wrong location. How can I make this work?
I have the following structure
TestCMake
CMakeLists.txt
app
TestOpenCV.cpp
CMakeLists.txt
thirdparty
installdir
opencv_mac
bin
include
lib
share
TopLevel CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
project(Tutorial VERSION 1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(OpenCV REQUIRED PATHS "thirdparty/installdir/opencv_mac/lib/cmake/opencv4/" NO_DEFAULT_PATH)
include_directories(SYSTEM ${OpenCV_INCLUDE_DIRS})
add_subdirectory(app)
App level CMakeLists
add_executable(TestOpenCV TestOpenCV.cpp)
target_link_libraries(TestOpenCV ${OpenCV_LIBS})
install(TARGETS TestOpenCV
DESTINATION bin)
How can I make the binary work after installing it?

CMake with MinGW-w64 does not install built DLL, but it's being built fine

NB: The files referenced here are all given below the horizontal ruler a bit down.
This is the MWE derived from a project where I ran into this. CMake version used is 3.12.2 on Ubuntu 16.04 (16.04.6 to be precise).
The goal is to create a CMakeLists.txt which can be re-targeted to build a Windows DLL using the MinGW-w64 toolchain (apt-get install mingw-w64 on Ubuntu/Debian).
When using no explicit toolchain file (i.e. without -DCMAKE_TOOLCHAIN_FILE=...), all works as expected and the lib${PRJNAME}.so gets installed as desired. However, once I use the toolchain file given below, I only get the resulting import lib ${PRJNAME}Lib.dll.a but not the corresponding .dll file installed.
If I invoke the Bash script as follows:
./build.sh 2>&1 |grep '^-- Install'
the output is:
-- Install configuration: ""
-- Installing: /home/user/cmake-test/build-native/install-target/lib/libtest.so
-- Install configuration: ""
-- Installing: /home/user/cmake-test/build-windows/install-target/lib/test.dll.a
As you can see the native build installs the actual shared library, but the one targeting Windows only installs the import lib, not the DLL. What I'd expect to see is something like this:
-- Install configuration: ""
-- Installing: /home/user/cmake-test/build-native/install-target/lib/libtest.so
-- Install configuration: ""
-- Installing: /home/user/cmake-test/build-windows/install-target/lib/test.dll
-- Installing: /home/user/cmake-test/build-windows/install-target/lib/test.dll.a
What is it I am doing wrong here? It would seem that the install() function is invoked properly:
install(
TARGETS ${PRJNAME}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT library
)
Clearly ARCHIVE DESTINATION takes effect as that's where the import lib ends up. But why is the built .dll completely ignored here?
Side-note: I am aware of GNUInstallDirs, but that fell totally apart once I started cross-compiling for Windows. So I am setting the desired paths "manually" before invoking install().
build.sh (should be executable)
The script will first wipe the folders build-native and build-windows, if present, and then create those again. Then it will invoke cmake from these folders respectively, targeting using the system (native) toolchain and the MinGW-w64 toolchain respectively. Last but not least it will invoke the installation from these folders respectively.
So if you place this into an empty folder along with the other files this should not meddle with your data elsewhere in any way.
#/usr/bin/env bash
for i in native windows; do
D=build-$i
test -d $D && rm -rf $D
mkdir $D
[[ "$i" == "windows" ]] && TCFILE=mingw64-64bit.cmake
( set -x; cd $D && cmake .. -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=. ${TCFILE+-DCMAKE_TOOLCHAIN_FILE=$TCFILE} -DCMAKE_VERBOSE_MAKEFILE=ON )
( set -x; cd $D && cmake --build . --target install )
done
test.cpp
#ifdef _WIN32
# if defined(test_EXPORTS)
# define TEST_API __declspec(dllexport)
# else
# define TEST_API __declspec(dllimport)
# endif
#else
# define TEST_API
#endif
TEST_API void SomeFunction()
{
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
set(PRJNAME test)
set(TARGET_DIR "${CMAKE_CURRENT_BINARY_DIR}/install-target")
project(${PRJNAME})
add_library(${PRJNAME} SHARED test.cpp)
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
set(DLL_PREFIX)
set(DLL_POSTFIX Lib)
else()
set(DLL_PREFIX lib)
set(DLL_POSTFIX)
endif()
set_target_properties(
${PRJNAME}
PROPERTIES
PREFIX "${DLL_PREFIX}"
IMPORT_PREFIX "${DLL_PREFIX}"
DEBUG_POSTFIX "${DLL_POSTFIX}"
RELEASE_POSTFIX "${DLL_POSTFIX}"
CXX_STANDARD 11
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED ON
POSITION_INDEPENDENT_CODE 1
)
set(CMAKE_INSTALL_PREFIX ${TARGET_DIR})
set(CMAKE_INSTALL_LIBDIR lib)
set(CMAKE_INSTALL_INCLUDEDIR include)
install(
TARGETS ${PRJNAME}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT library
)
mingw64-64bit.cmake
set(CMAKE_SYSTEM_NAME Windows)
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc-posix)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++-posix)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
install(
TARGETS ${PRJNAME}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT library
)
According to the install command documentation the DLL file is considered a runtime object. I tested the example on Ubuntu 14.04.

cmake external projects command seems to ignore INSTALL_DIR

First off, I'm relatively new to cmake. I'm trying to use cmake to build a project with a single external dependency. I specify the INSTALL_DIR for the external project to be CMAKE_INSTALL_PREFIX, so it installs to the same place as the parent project. But when I run make, it ignores it and tries to install to /usr/local/lib.
Here's my CMakeList.txt:
cmake_minimum_required( VERSION 2.8 )
include( ExternalProject )
project( capture )
add_library( capture SHARED capture.cc )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
ExternalProject_Add( proj_exceptions
GIT_REPOSITORY /home/user/workspace/exceptions
INSTALL_DIR ${CMAKE_INSTALL_PREFIX}
)
add_library( exceptions SHARED IMPORTED )
set_property( TARGET exceptions
PROPERTY IMPORTED_LOCATION ${CMAKE_INSTALL_PREFIX}/lib/libexceptions.so
)
add_dependencies( exceptions proj_exceptions )
include_directories( ${CMAKE_INSTALL_PREFIX}/include )
target_link_libraries( capture exceptions )
install( TARGETS capture DESTINATION lib )
install( FILES capture.h DESTINATION include )
CMakeLists.txt for the external project looks like this:
cmake_minimum_required( VERSION 2.8 )
project( exceptions )
add_library( exceptions SHARED exceptions.cc )
install( TARGETS exceptions DESTINATION lib )
install( FILES exceptions.hh DESTINATION include )
It clones and builds the external project just fine, but it chokes on the install step:
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/libexceptions.so
CMake Error at cmake_install.cmake:42 (file):
file INSTALL cannot copy file
"/home/user/workspace/capture/build/proj_exceptions-prefix/src/proj_exceptions-build/libexceptions.so"
to "/usr/local/lib/libexceptions.so".
Makefile:66: recipe for target 'install' failed
As you can see, the install configuration is empty. Looking through the generated config for the external project, I found this in cmake_install.cmake:
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "/usr/local")
endif()
So, it seems that passing INSTALL_DIR to ExternalProject_Add doesn't set the install prefix. The install step succeeds, if I instead use:
ExternalProject_Add( proj_exceptions
GIT_REPOSITORY /home/djones/workspace/exceptions
CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
)
So what's the purpose of INSTALL_DIR then?
You're right for the purpose of INSTALL_DIR, but you may have missed some steps.
According the cmake 2.8 doc about external project:
Install Step
The INSTALL_DIR is underneath the calling project’s
binary directory. Use INSTALL_DIR to specify a different location.
Note that in addition to setting INSTALL_DIR, you also have to pass
-DCMAKE_INSTALL_PREFIX or --prefix to the CMake or configure command. It is not used automatically in the configure step since not all
projects follow this convention.
# [INSTALL_DIR dir]
You can refer to the install directory in your configure command, for
example:
CONFIGURE_COMMAND SOURCE_DIR/configure --prefix=INSTALL_DIR
# [INSTALL_COMMAND cmd...]
CMake-based projects use ‘cmake--build’ to build the install target.
Other projects use ‘make install’. Use INSTALL_COMMAND to customize
the install step. Use INSTALL_COMMAND “” to omit the install step. The
install command executes with the working directory set to
.
So try to update your cmake command, or use the custom INSTALL_COMMAND feature.

Assimp with cmake

I want to include assimp to my project using CMake. I have Ubuntu 14.04 LTE and QTCreator.
Project contain of main.cpp and linked libraries stored in libs directory.
Main CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(test)
find_package(OpenGL REQUIRED)
# libs contain external libaries
add_subdirectory (libs)
include_directories(
libs/glfw-3.0.4/include
libs/assimp-3.1.1/include/
)
set(allLibs
${GLFW_LIBRARIES}
${OPENGL_LIBRARY}
GLEW_LIB
assimp
)
add_executable(test
main/main.cpp
)
target_link_libraries(Manipulator glfw assimp ${allLibs} )
CMakeList.txt inside libs directory
### GLFW ###
add_subdirectory (glfw-3.0.4)
include_directories(
glfw-3.0.4/include/GLFW/
glew-1.11.0/include/
assimp-3.1.1/include/
)
set(OPENGL_LIBRARY
-lGL -lGLU -lXrandr -lXext -lX11 -lrt
${CMAKE_DL_LIBS}
${GLFW_LIBRARIES}
)
### GLEW ###
set(GLEW_SOURCE
glew-1.11.0/src/glew.c
)
add_library( GLEW_LIB STATIC
${GLEW_SOURCE}
)
target_link_libraries(GLEW_LIB
${OPENGL_LIBRARY}
)
### ASSIMP ###
# Zlib
add_subdirectory( assimp-3.1.1/contrib/zlib )
# Boost workaround
include_directories( assimp-3.1.1/code/BoostWorkaround )
add_definitions( -DASSIMP_BUILD_BOOST_WORKAROUND )
# Compile AssImp
add_subdirectory( assimp-3.1.1/code )
And I receive following error.
CMake Error at libs/assimp-3.1.1/code/CMakeLists.txt:725 (INSTALL):
install TARGETS given no ARCHIVE DESTINATION for static library target
"assimp".
This point's me to this
INSTALL( TARGETS assimp # 725 line
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
COMPONENT ${LIBASSIMP_COMPONENT})
How to correctly link this library?
This is a CMakeList.txt that I use to build my project.
All external libraries were stored in libs directory. Main file was stored in main directory.
cmake_minimum_required (VERSION 2.6)
project (Project name)
find_package(OpenGL REQUIRED)
#Adding external CMakeList.txt files
add_subdirectory(libs/glfw-3.1)
#add GLEW as STATIC library
add_library(GLEW STATIC libs/glew-1.11.0/src/glew.c libs/glew-1.11.0/include/GL/glew.h)
#add include directories
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
common/
libs/glfw-3.1/include/
libs/glew-1.11.0/include/
libs/glm/
libs/assimp-3.1.1/include/
libs/CImg_162/CImg.h
)
# set variables that are needed
set(ZLIB_LIBRARIES zlibstatic)
set(ENABLE_BOOST_WORKAROUND ON)
set(BUILD_STATIC_LIB ON)
set(BUILD_ASSIMP_TOOLS ON)
set(ASSIMP_BUILD_STATIC_LIB ON)
add_subdirectory(libs/assimp-3.1.1)
#Add my own liblary
add_subdirectory(common)
set(extLibs
${extLibs}
${GLFW_LIBRARIES}
)
add_executable (openGL main/main.cpp
Source/vertexShader.vs
Source/fragmentShader.fs
)
target_link_libraries(openGL common assimp GLEW glfw ${GLFW_LIBRARIES})
CMakelist.txt from Common looks like this:
add_library(common model.cpp)
This should work on Ubuntu 14.04. If some libraries are missing try to follow steps from this tutorial tutorial