CMake cannot find -'libraryname' when running 'make' - cmake

I'm learning CMake at the moment and I'm stuck with a problem.
I have a library(that I have created previously with CMake) named 'libLibraryName'(I know, not the best name). This library contains just one function that prints a message and was formed by combining two files(1 header file wtih the prototype of the function and one .cpp with it's implementation).
Now I put the function in a folder and I'm trying to make a .cpp file make use of this library. This is the structure of my folder(as you can see the library is in the .../Library folder).
.
├── build
├── CMakeLists.txt
├── include
│   └── header.h
├── Library
│   └── libLibraryName.so
├── main.cpp
└── src
└── header.cpp
I wrote this CMakeLists:
cmake_minimum_required(VERSION 3.5.1)
# Project name
project(Project_Name)
# Include the existing library's name and then link it's path
# Make sure to provide a valid library name
set( PROJECT_LINK_LIBS libLibraryName.so )
link_directories(/home/uidr0938/CMake_Exercises/Library)
# Add path of the header files
include_directories(include)
# Create an executable with your main application's code
add_executable(Application main.cpp)
# And link the library to that application
target_link_libraries(Application ${PROJECT_LINK_LIBS})
Then I went into build and ran 'cmake ..'. This worked. But then when I wrote 'make' I get this following error:
/usr/bin/ld: cannot find -lLibraryName
collect2: error: ld returned 1 exit status
CMakeFiles/Application.dir/build.make:94: recipe for target 'Application' failed
make[2]: *** [Application] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/Application.dir/all' failed
make[1]: *** [CMakeFiles/Application.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
It is if the program is looking for the library at a different path not the one I provide it with the link_directories command.
Please help me solve this so I can use that library with my main function.
Thank you.
I used a virtual linux machine for this example.

Related

Bitbake create cmake recipe from local sources

I'm trying to build a helloworld package example with a cmake recipe. My problem is bitbake give me an error because it can't find CMakeLists.txt in the /tmp/work/core2-64-poky-linux/helloworld/0.1-r0 folder.
The error :
helloworld-0.1-r0 do_configure: Execution of '/path-to-tmp/tmp/work/core2-64-poky-linux/helloworld/0.1-r0/temp/run.do_configure.28001' failed with exit code 1:
CMake Error: The source directory "/path-to-tmp/tmp/work/core2-64-poky-linux/helloworld/0.1-r0/files" does not appear to contain CMakeLists.txt.
My package is in my layer meta-mylayer/recipes-core/helloworld :
meta-mylayer/
├── conf
│   └── layer.conf
├── COPYING.MIT
├── README
└── recipes-core
└── helloworld
   ├── files
   │   ├── CMakeLists.txt
   │   └── main_helloworld.c
   └── helloworld_0.1.bb
My CMakeLists.txt :
cmake_minimum_required(VERSION 2.4)
project(helloworld)
file(GLOB_RECURSE files/*.c)
add_executable(app ${src_files})
install(TARGETS helloworld DESTINATION bin)
My helloworld_0.1.bb :
PN="helloworld"
PV="0.1"
P="${PN}-${PV}"
DESCRIPTION="This is my package helloworld"
LICENSE="CLOSED"
FILESEXTRAPATHS_prepend:="${THISDIR}/${PN}:"
RDEPENDS_${PN}+=""
DEPENDS+=""
DEPENDS+="cmake"
SRC_URI+="file://CMakeLists.txt file://main_helloworld.c"
S="${WORKDIR}/files"
inherit pkgconfig cmake
I can't find my files in /path-to-tmp/tmp/work/core2-64-poky-linux/helloworld/0.1-r0/*
Why files are not copied? I'm using yocto Dunfell.
Thanks for your help.
When you have files in SRC_URI they are installed in ${WORKDIR}.
The following recipe will do the trick:
DESCRIPTION="This is my package helloworld"
LICENSE="CLOSED"
SRC_URI+="file://CMakeLists.txt file://main_helloworld.c"
S="${WORKDIR}"
inherit pkgconfig cmake
Also, your CMakeLists.txt should not find files in files directory.
S is set to ${WORKDIR} because this is where the files from the file:// fetcher are put by default.
DEPENDS already has cmake-native in it from the cmake bbclass you inherited. You don't need to depends on cmake, because you depends on cmake-native (you need to execute cmake at build time, you don't need cmake headers or sources).
The FILESEXTRAPATHS that was added is already by default used by bitbake (and it's also not matching your directory layout).
PN and PV are gotten from the filename of the bb recipe, no need to set them again.

how to link cmake created library with main file?

Here i am creating a project . i am using cmake . i am not able to link cmake created shared library with my main application ??? My CMakeLists.txt file are as follows :
//tree -stucture of my project
├── CMakeLists.txt
├── include
│   ├── Account.h
│   ├── bankingSystem.h
│   ├── bankStruct.h
│   └── stdheader.h
├── main.cpp
└── src
├── Account.cpp
├── bankingSystem.cpp
└── main.cpp
//CMakeLists.txt
cmake_minimum_required(VERSION 3.17.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++11 -DPC_BUILD")
include_directories(
./include
)
link_directories(
/usr/local/lib)
#create a shared library to be linked with test application
add_library(
BANK SHARED
src/bankingSystem.cpp
src/Account.cpp
)
add_executable(
main main.cpp
)
message("BANK")
But i am getting Undefined Reference :
[ 60%] Built target BANK
[ 80%] Linking CXX executable main
CMakeFiles/main.dir/main.cpp.o: In function `main':
/home/pankaj/BANK/main.cpp:8: undefined reference to `BankingSystem::BankingSystem()'
/home/pankaj/BANK/main.cpp:19: undefined reference to `BankingSystem::Create_new_Account()'
...
collect2: error: ld returned 1 exit status
CMakeFiles/main.dir/build.make:103: recipe for target 'main' failed
make[2]: *** [main] Error 1
CMakeFiles/Makefile2:124: recipe for target 'CMakeFiles/main.dir/all' failed
make[1]: *** [CMakeFiles/main.dir/all] Error 2
Makefile:103: recipe for target 'all' failed
make: *** [all] Error 2

cmake how to avoid building lib everytime

file structure
├── a_lib
│   ├── a.cpp
│   └── a.h
├── CMakeLists.txt
└── main.cpp
CmakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(untitled)
set(CMAKE_CXX_STANDARD 11)
add_library(a_lib SHARED a_lib/a.cpp)
target_include_directories(a_lib PUBLIC a_lib/)
add_executable(untitled main.cpp)
target_link_libraries(untitled a_lib)
But every time I build the a_lib will be rebuilt when a_lib is not changed.
cmake --build /home/autocar/Workspace/untitled/cmake-build-debug --target untitled -- -j 4
[ 50%] Built target a_lib
[100%] Built target untitled
So what should I do, if I do not want to rebuild the linked library every time. It takes a long time when a_lib builds every time even without any changes.
Just one addition to arrowd's answer:
If you want to completely avoid check if any target is up to date, you can issue the following command:
cmake --build /home/autocar/Workspace/untitled/cmake-build-debug --target untitled/fast -- -j 4
Note that --target untitled is changed into --target untitled/fast.
You can add "/fast" to any target mentioned in CMakeLists.txt to trigger compilation without any additional checks. On the other hand, be extremely cautious, since this allows you create inconsistent results, in case when sources for a_lib are changed, and target a_lib should be compiled/linked as well.
Judging from this output
cmake --build /home/autocar/Workspace/untitled/cmake-build-debug --target untitled -- -j 4
[ 50%] Built target a_lib
nothing's actually gets rebuilt. CMake just checks that this target is up to date.
The compilation takes place when CMake prints Building CXX object a.cpp.o and linking is performed when Linking CXX library a_lib.so pops out. If you don't see these messages, the library doesn't get rebuilt.

CMake imported target found when configuring but generated build.make says target-NOTFOUND

I have a simple shared library libfool2.so with installed header fool2.h which are not from a CMake project. My project my_temp1 depends on fool2 so I write a FindFool2.cmake to make an imported target:
find_path(Fool2_INCLUDE_DIR fool2.h PATH_SUFFIXES fool2)
find_library(Fool2_LIB fool2)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Fool2
REQUIRED_VARS Fool2_INCLUDE_DIR Fool2_LIB
)
if(Fool2_FOUND AND NOT TARGET Fool2::Fool2)
add_library(Fool2::Fool2 SHARED IMPORTED)
set_target_properties(Fool2::Fool2 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Fool2_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${Fool2_LIB}"
)
endif()
The CMakeLists.txt for my_temp1 project is:
cmake_minimum_required(VERSION 3.3)
project(my_temp1)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/cmake_modules)
# FindFool2.cmake is in ${CMAKE_CURRENT_LIST_DIR}/cmake/cmake_modules
find_package(Fool2 REQUIRED)
if (TARGET Fool2::Fool2)
message(STATUS "target found")
endif()
add_executable(my_temp1 main.cpp)
target_link_libraries(my_temp1 Fool2::Fool2)
Now
$ tree ../__install
../__install/
├── include
│   └── fool2
│   ├── fool2.h
│   └── version.h
└── lib
└── libfool2.so
$ tree .
.
├── cmake
│   └── cmake_modules
│   └── FindFool2.cmake
├── CMakeLists.txt
└── main.cpp
$ cmake -H. -B_builds -DCMAKE_INSTALL_PREFIX=../__install
# some output omitted
-- target found
-- Configuring done
-- Generating done
-- Build files have been written to: /OMITTED/my_temp1/_builds
$ cmake --build _builds
CMakeFiles/my_temp1.dir/build.make:82: *** target pattern contains no '%'. Stop.
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/my_temp1.dir/all' failed
make[1]: *** [CMakeFiles/my_temp1.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
$ head -n 85 _builds/CMakeFiles/my_temp1.dir/build.make | tail -n 10
# External object files for target my_temp1
my_temp1_EXTERNAL_OBJECTS =
my_temp1: CMakeFiles/my_temp1.dir/main.cpp.o
my_temp1: CMakeFiles/my_temp1.dir/build.make
my_temp1: Fool2::Fool2-NOTFOUND
my_temp1: CMakeFiles/my_temp1.dir/link.txt
#$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/OMITTED/my_temp1/_builds/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable my_temp1"
$(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/my_temp1.dir/link.txt --verbose=$(VERBOSE)
The command $ cmake -H. -B_builds -DCMAKE_INSTALL_PREFIX=../__install finds fool2 because find_* commands searches in the CMAKE_INSTALL_PREFIX as well.
But why is there weird output my_temp1: Fool2::Fool2-NOTFOUND in build.make?
CMake version is 3.11.3
For IMPORTED library target value -NOTFOUND corresponds to absent IMPORTED_LOCATION property, corresponded to the library's path. You need to set that property for correctly work with IMPORTED target.
If you want CMake target to be a placeholder just for link with other libraries, use INTERFACE library target instead: such library target doesn't have library location.

CTest not detecting tests

I have a project with a structure
├── CMakeLists.txt
├── mzl.c
├── mzl.h
└── tests
├── CMakeLists.txt
├── mzl-communication-test.c
├── mzl-setup-test.c
├── mzl-test-errors.c
└── mzl-test-errors.h
Where the top directory CMakeLists.txt file is
project(mzl)
cmake_minimum_required(VERSION 2.8)
add_subdirectory(tests)
# Enable testing for the project
enable_testing()
# Find zmq
find_library(ZMQ_LIB zmq REQUIRED)
message(STATUS "ZMQ Library: ${ZMQ_LIB}")
# Find threading library
set(CMAKE_THREAD_PREFER_PTHREAD ON)
find_package(Threads REQUIRED)
message(STATUS "Threading Library: ${CMAKE_THREAD_LIBS_INIT}")
# Set include directories for headers
set (
MZL_INCLUDE_DIRS
${CMAKE_SOURCE_DIR}
CACHE STRING "MZL Include Directories"
)
include_directories(${MZL_INCLUDE_DIRS})
# Set source files
set (
MZL_SRC_FILES
mzl.c
)
# Add library
add_library(${PROJECT_NAME} STATIC ${MZL_SRC_FILES})
# Link to zmq
target_link_libraries(${PROJECT_NAME} ${ZMQ_LIB} ${CMAKE_THREAD_LIBS_INIT})
and tests/CMakeLists.txt is
# Use MZL Source Directories (mzl headers are in top directory)
include_directories(${CMAKE_SOURCE_DIR})
# Variable from here is empty
message(STATUS "MZL Include Directories: ${MZL_INCLUDE_DIRS}")
# Files common to all tests
set ( TEST_COMMON_SOURCES
mzl-test-errors.c
)
# Library setup/shutdown testing
set(SETUP_TEST_NAME mzl-setup-test)
add_executable(${SETUP_TEST_NAME} ${TEST_COMMON_SOURCES} ${SETUP_TEST_NAME}.c)
target_link_libraries(${SETUP_TEST_NAME} ${PROJECT_NAME} ${ZMQ_LIB})
add_test(${SETUP_TEST_NAME} ${SETUP_TEST_NAME})
# Communcations test
set(COMMUNICATION_TEST_NAME mzl-communication-test)
add_executable(${COMMUNICATION_TEST_NAME} ${TEST_COMMON_SOURCES}
${COMMUNICATION_TEST_NAME}.c)
target_link_libraries(${COMMUNICATION_TEST_NAME} ${PROJECT_NAME}
${CMAKE_THREAD_LIBS_INIT} ${ZMQ_LIB})
add_test(${COMMUNICATION_TEST_NAME} ${COMMUNICATION_TEST_NAME})
Everything worked fine before I added the second test mzl-communication-test. After adding it and the lines in the tests/CMakeLists.txt after # Communications test, running ctest did nothing extra -- it still only ran the first test.
After deleting the build directory and running cmake again, I get no errors for the initial CMake run, but running make runs CMake again, resulting in an error with CMake:
CMake Error: Parse error in cache file build/CMakeCache.txt. Offending entry: include
followed by a Make error:
Makefile:203: recipe for target 'cmake_check_build_system' failed
make: *** [cmake_check_build_system] Error 1
Running make again results in everything being built, including the tests; however, running ctest results in
Test project build
No tests were found!!!
The issue seems to be with something that I am doing with CMake, but can't figure out what to do from here as I can't see anything that I'm doing differently than when it was originally working. Even my last commit to git, which was working when I committed it, is no longer working.
You need to move the enable_testing() call to be before you do add_subdirectory(tests)
# Enable testing for the project
enable_testing()
add_subdirectory(tests)