Linking error in project : cmake - c++

This is the directory structure of my project:
|-- CMakeLists.txt
|-- libdashframework
| |-- Buffer
| | |-- IMediaObjectBufferObserver.h
| | |-- MediaObjectBuffer.cpp
| | `-- MediaObjectBuffer.h
| |-- Input
| | |-- DASHReceiver.cpp
| | |-- DASHReceiver.h
| | |-- IDASHReceiverObserver.h
| | `-- MediaObject.h
| |-- MPD
| | |-- AbstractRepresentationStream.cpp
| | |-- AbstractRepresentationStream.h
| | |-- AdaptationSetStream.cpp
| | |-- AdaptationSetStream.h
| | |-- BaseUrlResolver.cpp
| | |-- BaseUrlResolver.h
| | |-- IRepresentationStream.h
| | |-- RepresentationStreamFactory.cpp
| | |-- RepresentationStreamFactory.h
| | |-- SegmentListStream.cpp
| | |-- SegmentListStream.h
| | |-- SegmentTemplateStream.cpp
| | |-- SegmentTemplateStream.h
| | |-- SingleMediaSegmentStream.cpp
| | |-- SingleMediaSegmentStream.h
| | |-- TimeResolver.cpp
| | `-- TimeResolver.h
| `-- Portable
| |-- MultiThreading.cpp
| `-- MultiThreading.h
|-- libdash_test_automoc.cpp
|-- libdash_test.cpp
`-- Makefile
I am having a linking error in the project and can't figure out how to remove it.
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
file(GLOB test_source RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
libdashframework/MPD/*.cpp
libdashframework/Buffer/*.cpp
libdashframework/Input/*.cpp
libdashframework/Portable/*.cpp
libdash_test.cpp )
add_executable(libdash_test ${test_source})
target_link_libraries(libdash_test dash -lpthread)
Error:
Linking CXX executable libdash_test
CMakeFiles/libdash_test.dir/libdashframework/Buffer/MediaObjectBuffer.cpp.o: In function `libdash::framework::buffer::MediaObjectBuffer::SetEOS(bool)':
MediaObjectBuffer.cpp:(.text+0x55d): undefined reference to `libdash::framework::input::MediaObject::AbortDownload()'
CMakeFiles/libdash_test.dir/libdashframework/Input/DASHReceiver.cpp.o: In function `libdash::framework::input::DASHReceiver::GetNextSegment()':
DASHReceiver.cpp:(.text+0x48e): undefined reference to `libdash::framework::input::MediaObject::MediaObject(dash::mpd::ISegment*, dash::mpd::IRepresentation*)'
CMakeFiles/libdash_test.dir/libdashframework/Input/DASHReceiver.cpp.o: In function `libdash::framework::input::DASHReceiver::GetSegment(unsigned int)':
DASHReceiver.cpp:(.text+0x57f): undefined reference to `libdash::framework::input::MediaObject::MediaObject(dash::mpd::ISegment*, dash::mpd::IRepresentation*)'
CMakeFiles/libdash_test.dir/libdashframework/Input/DASHReceiver.cpp.o: In function `libdash::framework::input::DASHReceiver::GetInitSegment()':
DASHReceiver.cpp:(.text+0x615): undefined reference to `libdash::framework::input::MediaObject::MediaObject(dash::mpd::ISegment*, dash::mpd::IRepresentation*)'
CMakeFiles/libdash_test.dir/libdashframework/Input/DASHReceiver.cpp.o: In function `libdash::framework::input::DASHReceiver::DownloadInitSegment(dash::mpd::IRepresentation*)':
DASHReceiver.cpp:(.text+0x9b0): undefined reference to `libdash::framework::input::MediaObject::StartDownload()'
CMakeFiles/libdash_test.dir/libdashframework/Input/DASHReceiver.cpp.o: In function `libdash::framework::input::DASHReceiver::DoBuffering(void*)':
DASHReceiver.cpp:(.text+0xa84): undefined reference to `libdash::framework::input::MediaObject::StartDownload()'
DASHReceiver.cpp:(.text+0xab5): undefined reference to `libdash::framework::input::MediaObject::WaitFinished()'
collect2: error: ld returned 1 exit status
make[2]: *** [libdash_test] Error 1
make[1]: *** [CMakeFiles/libdash_test.dir/all] Error 2
make: *** [all] Error 2
How can I remove this linking error?
After reading other similar questions, I have tried and changed the order of files in file() function. The order is similar to a working sample project so I think thats not the problem.
EDIT:
Although I had already linked the so file of libdash by putting it in the /usr/bin and /usr/lib/ dir. But I also updated the cmake too. It still didn't help.
updated CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(libdash_test)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_MODULE_PATH})
set(CMAKE_CXX_FLAGS "-D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS")
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
#libdash has to be manually installed
set (DASH_INCLUDE_DIR /usr/include/libdash)
find_package(DASH REQUIRED)
link_directories(${DASH_LIBRARIES})
#set(LIBDASH_LIBRARIES "../build/bin" CACHE PATH "Path to libdash.so")
#set(LIBDASH_INCLUDES "../libdash/include/" CACHE PATH "Path to libdash includes")
file(GLOB test_source RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
libdashframework/MPD/*.cpp
libdashframework/Buffer/*.cpp
libdashframework/Input/*.cpp
libdashframework/Portable/*.cpp
libdash_test.cpp )
add_executable(libdash_test ${test_source})
target_link_libraries(libdash_test DASH -ldash ${DASH_LIBRARIES} -lpthread)
Error in the current CMakeLists.txt (the one under EDIT):
CMake Error at CMakeLists.txt:20 (find_package):
By not providing "FindDASH.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "DASH", but
CMake did not find one.
Could not find a package configuration file provided by "DASH" with any of
the following names:
DASHConfig.cmake
dash-config.cmake
Add the installation prefix of "DASH" to CMAKE_PREFIX_PATH or set
"DASH_DIR" to a directory containing one of the above files. If "DASH"
provides a separate development package or SDK, be sure it has been
installed.
-- Configuring incomplete, errors occurred!

Related

CMake - No rule exists to target

In Ubuntu, I have downloaded a third-party shared library (liba1.so), placed in /lib/extern/lib . The associated header files I placed in /lib/extern/include. My own header files are placed in /include/public/ and /include/private/ . And now (to test mylib) I want to link this in my main.cpp code, using CMake.
My structure:
**My structure:**
|
|
+---CMakeLists.txt
|
+---lib
| |
| +---extern
| |
| +---lib
| | |
| | +---liba.so
| | +---libb.so
| | +---liba12.so
| |
| +---include
| |
| +...headers.h
|
+---include
| |
| +---public
| | |
| | +---file1.hpp
| | +...
| |
| +---private
| |
| +---file2.hpp
| +...
|
+---src
|
+---public
| |
| +---file1.cpp
| +...
|
+---private
| |
| +---file2.cpp
| +...
|
+---main.cpp
My CMakeLists.txt:
cmake_minimum_required(VERSION 3.9...3.19)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_VERSION})
endif()
project(mylib VERSION 0.0.1 DESCRIPTION "Test" LANGUAGES CXX )
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -DTPM_POSIX")
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_library(${PROJECT_NAME} STATIC src/private/file2.cpp src/public/file1.cpp )
add_library(lib SHARED IMPORTED)
set_target_properties(lib PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/lib/extern/lib/liba.so)
set_target_properties(lib PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/lib/extern/lib/libb.so)
set_target_properties(lib PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/lib/extern/lib/liba12.so)
target_link_libraries(${PROJECT_NAME} PUBLIC lib)
target_include_directories(${PROJECT_NAME}
PUBLIC
$<INSTALL_INTERFACE:lib/extern/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib/extern/include>
$<INSTALL_INTERFACE:include/public>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/public>
$<INSTALL_INTERFACE:include/private>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/private>
)
add_executable(test src/main.cpp)
target_link_libraries(test PRIVATE mylib)
ERROR:
[build] Consolidate compiler generated dependencies of target mylib
[build] [ 60%] Built target mylib [build] Consolidate compiler generated dependencies of target test
[build] gmake[2]: *** No rule exists to target „lib/extern/lib/liba12.so“,
[build] required by „test“ to create. Ending.
[build] gmake[1]: *** [CMakeFiles/Makefile2:111: CMakeFiles/test.dir/all] Error 2
[build] gmake: *** [Makefile:91: all] Error 2
[proc] The command: /usr/bin/cmake --build /home/mathew/proj/build --config Debug --target all -j 10 -- exited with code: 2 and signal: null [build] Build finished with exit code 2
Your imported files are relative to the source directory, not the build directory. You need to use CMAKE_CURRENT_SOURCE_DIR instead of CMAKE_CURRENT_BINARY_DIR when setting IMPORTED_LOCATION.

Some headers-only files in my project cannot include "SFML/Graphics.hpp" using CMake and Vscode

I'm new to C++ and CMake and started a big project. Im using VScode as my text editor and CMake as my build tool.
The problem is that i can include "SFML/Graphics.hpp in all my header files that has a source file with the same name, but in header-only files if i include "SFML/Graphics.hpp" or any other file that include "SFML/Graphics" cmake won't build and returns an error.
Here's is my code
Project Directory Tree
Game|> (root)
|- CMakeLists.txt
|> include
| |- BaseComponent.hpp (Header-only)
| |- TransformComponent.hpp (Header-only)
| |- CombatComponent.hpp (Header-only)
| |- MovementComponent.hpp (Header-only)
| |- Constants.hpp (Header-only)
| |- TimeUtils.hpp (Header-only)
| |- EcsManager.hpp
| |- EntityManager.hpp
| |- Game.hpp
| |- GameContext.hpp (Header-only)
| |- Scene.hpp (Header-only)
| |- GameScene.hpp
| |- System.hpp
| |- Input.hpp
| |- MovementSystem.hpp
| |- RenderableSystem.hpp
|> src
| |- CMakeLists.txt
| |- main.cpp
| |- Game.cpp
| |- EntityManager.cpp
| |- SceneManager.cpp
| |- Input.cpp
| |- GameScene.cpp
| |> Ecs
| |- CMakeLists.txt
| |- EcsManager.cpp
| |- System.cpp
| |> Systems
| |- CMakeLists.txt
| |- MovementSystem.cpp
| |- RenderableSystem.cpp
|
|> bin
|> build
CMakeLists.txt - Root
project(RPG)
set(CMAKE_TOOLCHAIN_FILE
"C:/Users/dante/vcpkg/scripts/buildsystems/vcpkg.cmake")
set(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/bin")
set(SOURCES src/EntityManager.cpp src/Game.cpp src/GameScene.cpp
src/main.cpp src/SceneManager.cpp src/Input.cpp)
include_directories("${PROJECT_SOURCE_DIR}/include")
add_subdirectory(src)
find_package(SFML 2.5.1 COMPONENTS REQUIRED graphics window system network
audio)
find_package(nlohmann_json 3.2.0 REQUIRED)
add_executable(RPG ${SOURCES})
target_link_libraries(RPG sfml-graphics sfml-window sfml-system sfml-
network sfml-audio)
target_link_libraries(RPG nlohmann_json::nlohmann_json)
target_link_libraries(RPG ECS)
CMakeLists.txt - src
add_subdirectory(Ecs)
CMakeLists.txt - Ecs
add_subdirectory(Systems)
add_library(ECS EcsManager.cpp System.cpp )
target_link_libraries(ECS ECS_SYSTEMS)
CMakeLists.txt - Systems
add_library(ECS_SYSTEMS MovementSystem.cpp RenderableSystem.cpp)
The erro that Cmake outputs is : 'SFML/Graphics.hpp': No such file or directory MSVC(C1083)
If i include "SFML/Graphics.hpp" in any "Any"Component Class it gives error
If i include "SFML/Graphics.hpp" in a .hpp file that have a .cpp file associated with it and include that class in "Any"Component Class (or any other header-only) it gives error.
I can't find any solution to that in stackoverflow.
Don't judge my folder structure it was different when the error first came up... than i changed to that to see if the CMake would build.
You need to add the SFML include directory to the list of include directories.
After
find_package(SFML 2.5.1 COMPONENTS REQUIRED graphics window system network audio)
add the line
include_directories(${SFML_INCLUDE_DIR})

How to structure cmake project with 2 main src files

I would like to understand how to structure my cpp project correctly. I am using the build generator CMAKE. The build system I am using is Ninja. I have 2 main functions in my project. Each main should be compiled into a different executable.
When and why should I use multiple cmake files?
How can I better structure my project?
|-- CMakeLists.txt
|-- README.md
|-- env.csh
|-- include
| |-- Pen.h
| |-- Cup.h
| |-- Clip.h
| |-- Fun.h
| |-- Ins.h
| |-- Ne.h
| `-- Pa.h
|-- libs
|-- src
| |-- Pen.cpp
| |-- Cup.cpp
| |-- Clip.cpp
| |-- Fun.cpp
| |-- Ins.cpp
| |-- Ne.cpp
| |-- Pa.cpp
| |-- main0.cpp
| `-- main1.cpp
`-- tests
`-- test.cpp
You need one add_executable() line for each executable in your project. Try this CMakeLists.txt file (written mostly from memory):
cmake_minimum_required(VERSION 2.8)
project(myproject LANGUAGES CXX)
enable_testing()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
set(SOURCES
src/Pen.cpp
src/Cup.cpp
src/Clip.cpp
src/Fun.cpp
src/Ins.cpp
src/Ne.cpp
src/Pa.cpp
)
add_executable(main0 src/main0.cpp ${SOURCES})
add_executable(main1 src/main1.cpp ${SOURCES})
add_executable(unittests tests/test.cpp ${SOURCES})
add_test(tests unittests)

Including header files with full path VisualStudio c++

Let's say I have such project structure
|-- DynamicLoader
| `-- dmc
| |-- DynamicLoader.h
| |-- Loader
| | |-- DynamicLibrary.cpp
| | |-- DynamicLibrary.h
| | |-- LibraryManager.cpp
| | |-- LibraryManager.h
| |-- Utils
| | |-- Utils.h
| |-- dmc.cpp
| |-- dmc.h
where dmc.h is my pre-compiled header.
I want to use it for example in my source files located in Loader folder like this: #include "dmc/dmc.h
but the intelisense complains about it and I have to use those semantics:
#include "../dmc.h"
is there anyway to achieve this in visual studio? I've seen one project that worked similarly to this but I couldn't figure it out by myself

How to get the target generated from Repository() path in to Variant_dir path instead of Sconstruct folder

I am able to locate the specific file by giving the path in Repository().
But the output generated is in the Sconstruct directory instead of in the
variant_dir.
Please let me know how to resolve this issue
Explaining the problem specifically
The tree structure in the project looks as below.
tree .
.
|-- SConstruct
|--Build
| `-- SConscript_unitTest
|--FileB_mock.o
|--FileA.o
|-- _Output
| `-- unit_test
| |--FileA_unittest.o
`-- moduleA
| |-- FileA.cpp
| `-- UnitTest
| |-- FileA_unittest.cpp
| `-- SConscript
`-- moduleB
| |-- FileB.cpp
| `-- UnitTest
| |-- FileB_unittest.cpp
| `-- SConscript
`-- Mocks
`-- moduleA
| |-- FileA_mock.cpp
| `-- FileA_mock.h
`-- moduleB
|-- FileB_mock.cpp
`-- FileB_mock.h
For the above structure,
In the SConstruct i make the call to SConscript_unitTest.
Implementation of Sconscript_unitTest is
'SConscript('#\moduleA\UnitTest\SConscript',
variant_dir = '#_Output\unit_test'), duplicate=0)'
Implementation of moduleA\UnitTest\Sconscript is
Sources = [ 'FileA_unittest.cpp',
'#FileB_mock.cpp',
'#FileA.cpp'
]
Repository( '#\ModuleA', '#\Mocks\ModuleB')
obj_files = Object(Sources)
Program(target_name, obj_files)
As shown in the Heirarchical diagram, FileA_unittest.o falls in the intended variant_dir, but FileB_mock.o and FileA.o are in the root folder.
I am not sure what i have done here is the best mechanism .. as i am translating an existing make project to scons.
Hope i have given enough detail of the problem.