Debug postfix messes up linking SDL2 with CMake - c

I am trying to set up a project with the SDL2 library using CMake. When i compile for release everything works fine. However when setting the build type to debug compilation fails with the following error:
*** No rule to make target 'Lib/SDL2/libSDL2d.a', needed by '../Bin/Template'. Stop.
It seems like SDL2 adds a postfix for debug builds and that messes things up.
This is the CMakeLists.txt im using:
cmake_minimum_required(VERSION 3.2.0)
project(Template)
add_subdirectory(Lib/SDL2)
# C Standard
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
# compile with debug info
set(CMAKE_BUILD_TYPE Debug)
# output directories
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Bin)
# build directory
set(CMAKE_BUILD_DIRECTORY ${CMAKE_SOURCE_DIR}/Build)
include_directories(
Source
Lib/SDL2/include
)
set(SOURCES
Source/main.c
)
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} SDL2-static)
I don't want to use find_packge and include the SDL2 source code directly into my project.
What do i need to change to be able to compile for debug?

The SDL2 code should add the postfix d to the built library name when CMAKE_BUILD_TYPE is set to Debug (see the SDL2 code snippet here). What appears to be the issue here is the placement of the line:
set(CMAKE_BUILD_TYPE Debug)
in your CMake file. You probably initially built this in the Release configuration. But when switching it to Debug, the change is not applied to SDL2 because CMAKE_BUILD_TYPE is set after traversing to the Lib/SDL2 directory. You can correct this by moving the set() command before the call to add_subdirectory():
# Set the build type first!
set(CMAKE_BUILD_TYPE Debug)
add_subdirectory(Lib/SDL2)
You can avoid these issues by setting the build configuration at the command line instead, which is the more common and accepted CMake convention:
cmake -DCMAKE_BUILD_TYPE=Debug ..

Related

What am I doing wrong making SDL2 usable in Clion? [duplicate]

I'm looking for the simplest way to compile a c++ program using SDL2 and SDL_image with cmake.
Here is my best attempt, after hours of searching:
CMakeLists.txt
project(shooter-cmake2)
cmake_minimum_required(VERSION 2.8)
set(SOURCES
shooter.cpp
classes.cpp
utils.cpp
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_executable(${PROJECT_NAME} ${SOURCES})
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2_image REQUIRED sdl2_image)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARY})
I get these errors:
In function `loadTexture(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, SDL_Renderer*)':
undefined reference to `IMG_LoadTexture'
collect2: ld returned 1 exit status
Here is the function call:
#include "SDL.h"
#include "SDL_image.h"
SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren){
SDL_Texture *texture = IMG_LoadTexture(ren, file.c_str());
texture != nullptr or die("LoadTexture");
return texture;
}
I think that the following will work, as it finds the libraries on my ubuntu system and the example function you provided can link:
project(shooter-cmake2)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_executable(${PROJECT_NAME} src/test.cpp)
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES})
If cmake is executed with --debug-output it outputs:
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.26")
Called from: [2] /usr/share/cmake-2.8/Modules/FindPkgConfig.cmake
[1] $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
-- checking for one of the modules 'sdl2'
Called from: [1] $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
-- checking for one of the modules 'SDL2_image>=2.0.0'
Called from: [1] $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
This made me check the contents of
/usr/lib/x86_64-linux-gnu/pkgconfig/sdl2.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/SDL2_image.pc
I noticed that SDL2_image.pc contains
Name: SDL2_image
which I assumed should match the third parameter to PKG_SEARCH_MODULE for this library.
There are two blog posts about this here:
Using SDL2 with CMake
Using SDL2_image with CMake
Basically you need a FindSDL2.cmake and FindSDL2_image.cmake module. They can be based of the ones that work for SDL 1.2 which are included in CMake already. Using these Find modules will also work on Windows.
If you are on Linux and only need SDL2 you don't even need the FindSDL2.cmake as the following already works:
cmake_minimum_required(VERSION 3.7)
project(SDL2Test)
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
add_executable(SDL2Test Main.cpp)
target_link_libraries(SDL2Test ${SDL2_LIBRARIES})
I was having trouble with these answers, I think cmake changed the way to import targets. Following #trenki blog post I needed to change my CMakeLists.txt to:
project(SDL2Test)
find_package(SDL2 REQUIRED COMPONENTS SDL2::SDL2)
add_executable(SDL2Test main.cpp)
target_link_libraries(SDL2Test SDL2::SDL2)
Currently this works out of the box on Arch Linux.
I introduced a modern and portable approach for linking to the SDL2, SDL2_image. These SDL2 CMake modules let you build an SDL2 & SDL2_image project as follows :
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
target_link_libraries(${PROJECT_NAME} SDL2::Main SDL2::Image)
You should just clone the repo in your project:
git clone https://github.com/aminosbh/sdl2-cmake-modules cmake/sdl2
Note: If CMake didn't find the SDL2/SDL2_image libraries (in Windows), we can specify the CMake options SDL2_PATH and SDL2_IMAGE_PATH as follows:
cmake .. -DSDL2_PATH="/path/to/sdl2" -DSDL2_IMAGE_PATH="/path/to/sdl2-image"
It supports also other related libraries : SDL2_ttf, SDL2_net, SDL2_mixer and SDL2_gfx. For more details, please read the README.md file.
You can find a list of examples/samples and projects that uses these modules here : https://github.com/aminosbh/sdl-samples-and-projects
Since 2.6 version, SDL2_image installation is shipped with CMake config script SDL2_imageConfig.cmake/SDL2_image-config.cmake.
So find_package(SDL2_image) works without any additional FindSDL2_image.cmake module, and creates IMPORTED target SDL2_image::SDL2_image:
find_package(SDL2_image REQUIRED)
target_link_libraries(<executable-target> SDL2_image::SDL2_image)
Note, that variables like SDL2_IMAGE_LIBRARIES or SDL2_IMAGE_INCLUDE_DIRS are NOT set in this case, so using them is meaningless.
The following commands works fine for me:
set(SDL_INCLUDE_DIR "/usr/include/SDL2")
set(SDL_LIBRARY "SDL2")
include(FindSDL)
if(SDL_FOUND)
message(STATUS "SDL FOUND")
endif()

How to include header files in external library in CMake

I have a C application which is running on Raspberry Pi 3 and currently, I have to build it on PI with Cmake. I am trying to build it on Ubuntu machine. I have added a CMAKE_TOOLCHAIN_FILE as described here.
I could run cmake. -DCMAKE_TOOLCHAIN_FILE without any problem but the "make" command is not successful and it can not find a header file inside one of the external library: "mirsdrapi-rsp". The error message is:
fatal error: mirsdrapi-rsp.h: No such file or directory
#include "mirsdrapi-rsp.h"
^
compilation terminated.
I have created a folder named "lib" and have put the "libmirsdrapi-rsp.so" file inside it.
my CMakeLists.txt is as below:
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wextra -v -g -D_XOPEN_SOURCE")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Wextra -v ")
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "-v")
set (SDR_API_PATH ${CMAKE_SOURCE_DIR}/lib)
include_directories (include ${SDR_API_PATH})
include_directories("${CMAKE_SOURCE_DIR}/lib")
find_library(mirslocation NAMES mirsdrapi-rsp HINTS ${SDR_API_PATH} NO_CMAKE_FIND_ROOT_PATH)
message(STATUS ${mirslocation})
add_library(mirs STATIC IMPORTED)
set_target_properties(mirs PROPERTIES IMPORTED_LOCATION ${mirslocation})
target_link_libraries (raspberryPiDaemon mirs)
target_link_libraries(raspberryPiDaemon m)
Cmake is printing the right path of the library mirsdrapi-rsp while running "find_library" and as I mentioned I am getting the error message just while running "make" command and not "cmake" command.
My content of CMAKE_TOOLCHAIN_FILE is as below:
# Define our host system
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
# Define the cross compiler locations
SET(CMAKE_C_COMPILER ${CMAKE_SOURCE_DIR}/../tools-master/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER ${CMAKE_SOURCE_DIR}/../tools-master/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc)
# Define the sysroot path for the RaspberryPi distribution in our tools folder
SET(CMAKE_FIND_ROOT_PATH ${CMAKE_SOURCE_DIR}/../tools-master/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/sysroot/SET)
# Use our definitions for compiler tools
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Search for libraries and headers in the target directories only
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
add_definitions(-Wall -std=c11)
Anybody knows how I can add the header file from mirsdrapi-rsp library to include path?
I guess that you're setting include_directories to the wrong path (it is set 2 times to ${CMAKE_SOURCE_DIR}/lib which must be the folder of libraries not the header files). Check again the correct location of the missing header file.
More precisely: you need to find the path of mirsdrapi-rsp.h and let CMake know it just like for find_library:
find_path(MIRSDRAPI_INCLUDE_DIRS NAMES mirsdrapi-rsp.h PATHS {proper-location})
if (MIRSDRAPI_INCLUDE_DIRS)
target_include_directories(raspberryPiDaemon PRIVATE ${MIRSDRAPI_INCLUDE_DIRS})
endif()
In addition, you can set the INTERFACE_INCLUDE_DIRECTORIES property to the library like this:
set_property(TARGET mirsdrapi-rsp APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MIRSDRAPI_INCLUDE_DIRS})
This way, target_include_directories might be unnecessary and target_link_directories should be enough.

C - configure cmake to propely link ncursesw

I'm building a school project application which requires the use of ncurses library. While trying to use mvwaddwstr() function, I get the following error: undefined reference to `mvwaddwstr'.
My CMake configuration file is as follows:
cmake_minimum_required(VERSION 3.0)
set(CMAKE_C_STANDARD 11)
project(client)
# Libraries
find_package(Curses REQUIRED)
find_package(Threads REQUIRED)
include_directories(${CURSES_INCLUDE_DIRS})
# Sources
set(CLIENT_SOURCE_FILES
main.c)
# Links
add_library(client_library ${CLIENT_SOURCE_FILES})
add_executable(client ${CLIENT_SOURCE_FILES})
target_link_libraries(client ${CURSES_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(client INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
Edit
As suggested I tried adding:
set(CURSES_NEED_NCURSES TRUE)
set(CURSES_NEED_WIDE TRUE)
include(FindCurses)
before the find_package line but it still ain't working.

CMake cross-compile with specific linker doesn't pass arguments to armlink

I am trying to cross-compile a project for embedded ARM Cortex builds, but I am unable to get the linker working. I want to use armlink, but no files are passed to armlink and hence no .elf file is produced.
My CMakeLists.txt is pretty simple and given below. The failure is shown after that which shows that armlink was invoked by the makefile without any arguments.
Any pointers will help - I searched and read many posts, but they all seem to have more involved requirements.
cmake_minimum_required(VERSION 2.8)
project(test_arm)
enable_language(C ASM)
# Cross-compilation for ARM
SET(CMAKE_C_COMPILER armcc)
SET(CMAKE_LINKER armlink)
SET(CMAKE_C_LINK_EXECUTABLE armlink)
SET(CMAKE_C_FLAGS "--cpu=Cortex-M3")
SET(LINK_FLAGS "--map --ro-base=0x0 --rw-base=0x0008000 --first='boot.o(RESET)' --datacompressor=off")
SET(CMAKE_EXE_LINKER_FLAGS "--map --ro-base=0x0 --rw-base=0x0008000 --first='boot.o(RESET)' --datacompressor=off")
include_directories(../include)
add_executable(blinky blinky.c)
set_target_properties(blinky PROPERTIES LINKER_LANGUAGE C)
The failure is as follows, but I guess it would be obvious to someone given that I have some stupid issue in my CMakeLists:
$ make VERBOSE=1
[100%] Building C object CMakeFiles/blinky.dir/blinky.c.o
/usr/bin/cmake -E cmake_link_script CMakeFiles/blinky.dir/link.txt --verbose=1
armlink
Linking C executable blinky
Product: DS-5 Professional 5.21.0 [5210017]
Component: ARM Compiler 5.05 update 1 (build 106)
Tool: armlink [4d0efa]
For support see http://www.arm.com/support/
Software supplied by: ARM Limited
Usage: armlink option-list input-file-list
where
....
I was expecting the CMake generated Makefile to invoke armlink with something like:
armlink --map --ro-base=0x0 --rw-base=0x0008000 \
--first='boot.o(RESET)' --datacompressor=off \
CMakeFiles/blinky.dir/blinky.c.o -o blinky.elf
Starting with CMake v3.5 you don't need a toolchain anymore for Keil ARM C/C++ compilation tools:
Support was added for the ARM Compiler (arm.com) with compiler id ARMCC.
Just set your C/CXX compiler variables accordingly
cmake -DCMAKE_C_COMPILER:PATH="C:\Program Files (x86)\DS-5\bin\armcc.exe"
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files (x86)\DS-5\bin\armcc.exe"
...
References
ARMCC toolchain support
Add support for the ARM Compiler (arm.com)
CMake Error at CMakeLists.txt:30 (project): No CMAKE_C_COMPILER could be found
From my experience, you cannot set CMAKE_EXE_LINKER_FLAGS in a CMakeLists.txt file. It has to be passed via a CMAKE_TOOLCHAIN_FILE when CMake is invoked the very first time in a build directory.
I don't find any documentation regarding this problem, but there is the cross-compilation with CMake page which you should use it if you do cross-compilation.
For a start, just put your set-calls in a toolchain file and run
cmake -DCMAKE_TOOLCHAIN_FILE=<yourfile.toolchain>
in a clean build directory.
A toolchain file may be a good idea. Here is what I've came up the last time I tried CMake 2.8.10 with the DS-5 toolchain (it could still be optimized, but it should give you a starting point):
INCLUDE(CMakeForceCompiler)
# This one is important
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_PROCESSOR arm)
# Specify the cross compiler
SET(CMAKE_C_COMPILER "C:/Program Files (x86)/DS-5/bin/armcc.exe")
SET(CMAKE_CXX_COMPILER "C:/Program Files (x86)/DS-5/bin/armcc.exe")
SET(CMAKE_AR "C:/Program Files (x86)/DS-5/bin/armar.exe" CACHE FILEPATH "Archiver")
#CMAKE_FORCE_C_COMPILER("C:/Program Files (x86)/DS-5/sw/gcc/bin/arm-linux-gnueabihf-gcc.exe" GNU)
#CMAKE_FORCE_CXX_COMPILER("C:/Program Files (x86)/DS-5/sw/gcc/bin/arm-linux-gnueabihf-g++.exe" GNU)
UNSET(CMAKE_C_FLAGS CACHE)
SET(CMAKE_C_FLAGS "--cpu=Cortex-A9 --thumb -Ospace" CACHE STRING "" FORCE)
UNSET(CMAKE_CXX_FLAGS CACHE)
SET(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS} CACHE STRING "" FORCE)
UNSET(CMAKE_EXE_LINKER_FLAGS CACHE)
SET(CMAKE_EXE_LINKER_FLAGS "" CACHE STRING "" FORCE)
UNSET(CMAKE_AR_FLAGS CACHE)
SET(CMAKE_AR_FLAGS "-p -armcc,-Ospace" CACHE STRING "" FORCE)
# set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> ${CMAKE_AR_FLAGS} -o <TARGET> <OBJECTS>" CACHE STRING "C Archive Create")
# set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> ${CMAKE_AR_FLAGS} -o <TARGET> <OBJECTS>" CACHE STRING "CXX Archive Create")
include_directories("C:/Program Files (x86)/DS-5/include")
#include_directories("C:/Program Files (x86)/DS-5/sw/gcc/arm-linux-gnueabihf/libc/usr/include/arm-linux-gnueabi")
# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH "C:/Program Files (x86)/DS-5")
# 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)
Regarding your question
Some failure analysis
What you have tried should work (see also e.g. How do I add a linker or compile flag in a CMake file?). But it seems something goes wrong during the configuration step.
I don't know your command line call for CMake's configuration/generation steps, so some general tips to find the root cause:
You could try calling
cmake.exe --trace ...
to see what went wrong with your CMAKE_EXE_LINKER_FLAGS variable. This will generate a lot of output, so here are some basics on what CMake does:
The project() command will trigger the compiler evaluation
This will write CMAKE_EXE_LINKER_FLAGS into your CMakeCache.txt
You are overwriting it with a local variable (see variable scope docu here)
If you look into share\cmake-2.8\Modules\CMakeCommonLanguageInclude.cmake:
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS_INIT} $ENV{LDFLAGS}"
CACHE STRING "Flags used by the linker.")
You could use CMAKE_EXE_LINKER_FLAGS_INIT, but you have to set it before the project() command or in the toolchain file.
Because you set the link language to C take a look into share\cmake-2.8\Modules\CMakeCInformation.cmake:
if(NOT CMAKE_C_LINK_EXECUTABLE)
set(CMAKE_C_LINK_EXECUTABLE
"<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endif()
So you can use CMAKE_C_LINK_EXECUTABLE to overwrite the complete linker call or you could use CMAKE_C_LINK_FLAGS to set additional flags.
The "official" way
The official way to set the target's linker and compiler flags would be (before CMake 2.8.12):
set_property(TARGET blinky APPEND_STRING PROPERTY COMPILE_FLAGS "--cpu=Cortex-M3")
set_property(TARGET blinky APPEND_STRING PROPERTIES LINK_FLAGS "--map --ro-base=0x0 --rw-base=0x0008000 --first='boot.o(RESET)' --datacompressor=off")
Starting with CMake 2.8.12 it would be something like:
add_compile_options("--cpu=Cortex-M3")

cpack cannot find libraries, target doesn't exist in this directory

EDIT ===================
The apr-1 is the apache portable runtime, which I downloaded and compiled myself to create the shared library (so its not made by cmake). I need to link against this library after I run CPack on the target system.
My development project directory:
read_config/bin
/libs
/include
/src
/build
For my CMakeLists.txt, everything installs ok, but now I have a linking problem, as it cannot find the new location of the library.
I have removed the LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/libs) as I don't need this now, as I am using the FIND_LIBRARY.
And added the following:
# Find the library in the libs folder
FIND_LIBRARY(APR_LIBS NAMES "apr-1" PATHS ${PROJECT_SOURCE_DIR}/libs)
# Print out the path to see if its correct
MESSAGE(${APR_LIBS})
# Link the library with the executable
TARGET_LINK_LIBRARIES(cfg ${APR_LIBS})
# Install the libs folder
INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/libs/
DESTINATION libs)
# Install the executable in the bin folder
INSTALL(TARGETS cfg
RUNTIME DESTINATION bin)
Everything installs ok, but when I check the executable to see what libraries it links against it cannot find the apr-1 as it looks in the wrong place.
libapr-1.so.0 => not found
This is because I have extracted the installation package to a new location which is different to where it was compiled from. From the compiled directory I get this, which runs ok:
libapr-1.so.0 => /home/devel/projects/read_config/libs/libapr-1.so.0 (0xf7746000)
I after I install I have this directory structure on the target installation machine, so the executable will link with the new libs/apr-1 library:
target directory/
/bin
/libs/apr-1
Many thanks for any further suggestions,
========================================
gcc (GCC) 4.7.2
cmake version 2.8.9
Fedora 17
Hello,
I am getting in the following error:
CMake Error at src/CMakeLists.txt:14 (INSTALL):
install TARGETS given target "apr-1" which does not exist in this
directory.
I have the following directory:
read_config/
/build - out of source build
/CMakeLists.txt
/include - apr include files
/libs - apr libraries
/src - project source files *.h *.c CMakeLists.txt
In my root CMakeLists.txt I have the following:
# Name of project and compiler to use
PROJECT(read_cfg C)
# Set compiler flags
IF(CMAKE_COMPILER_IS_GNUCC)
MESSAGE(STATUS "COMPILER IS GNUCC")
SET(CMAKE_C_FLAGS "-Wall -Wextra -m32 -Wunreachable-code -ggdb -O0 -D_DEBUG -D_LARGEFILE64_SOURCE")
ENDIF(CMAKE_COMPILER_IS_GNUCC)
# Where the include files can be found
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/read_config/include)
# Where the libraries can be found
LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/read_config/libs)
ADD_SUBDIRECTORY(src)
In my src directory I have the following CMakeLists.txt
# Create the executable and link the libraries into it
ADD_EXECUTABLE(cfg test_config.c)
# Place executable in bin directory
SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
# Add libraries
IF(CMAKE_COMPILER_IS_GNUCC)
MESSAGE(STATUS "Linking cfg library")
TARGET_LINK_LIBRARIES(cfg apr-1)
ENDIF(CMAKE_COMPILER_IS_GNUCC)
INSTALL(TARGETS cfg
RUNTIME
DESTINATION bin)
INSTALL(TARGETS apr-1
ARCHIVE
DESTINATION lib)
SET(CPACK_PACKAGE_NAME "rd_cfg")
SET(CPACK_PACKAGE_VENDOR "sun.com")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "rd_cfg - CPack read_config installation")
SET(CPACK_PACKAGE_VERSION "1.0.0")
SET(CPACK_PACKAGE_VERSION_MAJOR "1")
SET(CPACK_PACKAGE_VERSION_MINOR "0")
SET(CPACK_PACKAGE_VERSION_PATCH "0")
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "Read_config_install_dir")
INCLUDE(CPack)
The problem is this line here:
INSTALL(TARGETS apr-1
ARCHIVE
DESTINATION lib)
I have tried doing the following
INSTALL(TARGETS ${CMAKE_SOURCE_DIR}/libs/apr-1
ARCHIVE
DESTINATION lib)
But it still fails to find the library.
And also using the path like this:
INSTALL(TARGETS src/libs
ARCHIVE
DESTINATION lib)
I would like to be able to just put the directory there like this so I don't have to specifiy each library, but just the directory like this:
INSTALL(TARGETS ${CMAKE_SOURCE_DIR}/libs
ARCHIVE
DESTINATION lib)
So it can find all the libraries in that directory. I have about 5 of them.
Many thanks for any suggestions,
The error seems to be a result of calling install in a different CMakeLists.txt to that in which apr-1 is defined via add_library.
I guess you're doing add_library(apr-1 ...) in your root CMakeLists.txt, which means that's where you need to call install(TARGETS apr-1 ARCHIVE DESTINATION lib).
Note that the error message "...does not exist in this directory." is not referring to actual directories in the filesystem sense, but rather the notional directories which come about via add_subdirectory commands.
Edit
In light of your comments, it seems that the issue is that apr-1 is not an actual CMake target, but rather just a library.
In this case, the install command cannot be the TARGETS version, it would have to be install(FILES...) or install(DIRECTORY...). This would probably mean you'd have to locate the library using e.g. find_library in order to get a full path.
Further Edit
This further problem is as a result of not setting the correct RPATH flags. You need to add the following lines to your src/CMakeLists.txt before the ADD_EXECUTABLE call:
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/libs")
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/libs" isSystemDir)
IF("${isSystemDir}" STREQUAL "-1")
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/libs")
ENDIF("${isSystemDir}" STREQUAL "-1")
For a full explanation on these CMake variables, see the CMake Wiki on RPATH handling
try adding this to your CMakeLists.txt
set(CMAKE_INSTALL_RPATH $LIBRARY_OUTPUT_PATH)

Resources