cmake errors: Cannot find source file - c++

I'm trying to use cmake for the first time and I'm having a hard time getting this to work. There's a source file and a library file (Lab_4.cpp and Trip_4.cpp, respectively) and they're both in the source folder (Lab_4). Here's what's in my cmake file so far:
cmake_minimum_required (VERSION 2.6)
project (Lab_4)
#add executable
add_executable(Lab_4 ${PROJECT_SOURCE DIR}/Lab_4.cxx)
target_link_libraries (Lab_4 ${EXTRA_LISTS})
#add libraries
add_library (${PROJECT_SOURCE_DIR}/Trip.cxx)
ls shows both files are in that folder. I'm really new to cmake so I'm sure I'm making an obvious mistake but I have no idea what it is. Any help would be appreciated!

cmake_minimum_required(VERSION 2.6)
project(Lab_4)
add_library(Trip_4 Lab_4/Trip4.cpp)
add_executable(Lab_4 Lab_4/Lab_4.cpp)
target_link_libraries(Lab_4 Trip_4 ${EXTRA_LISTS})
Your exact intentions are not completely clear, but the above are the simplest possible instructions according to your current question description.
Are you absolutely sure your CMake is version 2.6? You should update the version to whatever CMake you are currently using (type cmake --version to find out).

To add your sources to CMake project, you can use the aux_source_directory command. If your sources are in Lab_4 folder, then you can do the following:
project(Lab_4)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/Lab_4 LAB4_SOURCES)
add_executable(Lab_4 ${LAB4_SOURCES})
The CMAKE_CURRENT_SOURCE_DIR is the path of the directory where the current CMakeFiles.txt is. The example above won't build Trip_4.cpp as a library but use it as another source file together with Lab_4.cpp.
If you wish to build the Trip_4.cpp as library fist I recommend to separate it from Lab_4.cpp to make later uses easier. An example directory structure could be:
MyProject/
|-- app/
| |-- src/
| | `-- Lab_4.cpp
| |-- inc/
| `-- CMakeLists.txt
|-- lib/
| |-- src/
| | `-- Trip_4.cpp
| |-- inc/
| `-- CMakeLists.txt
`-- CMakeLists.txt
In this case the MyProject/lib/CMakeLists.txt will contain something like the following:
project(Trip_4)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src TRIP4_SOURCES)
add_library(Trip_4 ${TRIP4_SOURCES})
The MyProject/app/CMakeLists.txt will be almost the same as I showed in my first example, except now it has to maintain its dependency on Trip_4 library:
project(Lab_4)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../lib
${CMAKE_CURRENT_SOURCE_DIR}/inc
)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src LAB4_SOURCES)
add_executable(Lab_4 ${LAB4_SOURCES})
add_dependencies(Lab_4 Trip_4)
target_link_libraries(Lab_4 Trip_4)
Finally, the MyProject/CMakeLists.txt has to tie together the library and the executable subprojects as follows:
project(MyProject)
add_subdirectory(lib)
add_subdirectory(app)

Related

Include particular header files in a cmake project with absolute paths

to start with, I have the following repo structure.
root
|
|--- blocks
| |
| |---example
| |
| |---example.cpp
| |---CMakeLists.txt
|
|--- interfaces
|
|--- types
|
|-- types1.h
|-- types2.h
|-- CMakeLists.txt
What I would like to do is to only include types1.h in the cmake target of example.cpp. And I would like to include types1.h such that I can include it in example.cpp using its path relative to root (i.e. #include "interfaces/types/types1.h") and I don't want to use include_directories(${CMAKE_SOURCE_DIR}) since that would expose the whole repo to the target.
target_include_directories did not work since it only includes directories but not individual files and I don't want to include a whole directory and expose irrelevant headers in types folder to example.cpp or move types1.h to a dedicated subfolder.
Do you have any suggestions on how to achieve this?
My current solution is as below which gives fatal error: interfaces/types/types1.h: No such file or directory when I compile exampleblock target. (I eased the requirements for start and allowed interface_types target to include types2.h also even though example.cpp doesn't need it)
blocks/example/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
add_library(exampleblock STATIC
example.cpp
)
target_link_libraries(exampleblock INTERFACE
${CMAKE_SOURCE_DIR}/interfaces/types:interface_types
)
interfaces/types/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
add_library(interface_types INTERFACE)
target_include_directories(interface_types INTERFACE .)

cmake avoid re-build all for test

I want to avoid build twice all sources for my test... I have the following project tree:
|-- my_executable
|-- CMakeFiles.txt
|-- resources
|-- include
|-- src
|-- CMakeFiles.txt
|-- *.cpp
|-- test
|-- CMakeFiles.txt
|-- test.cpp
The problem is that for building test I need the same sources of my_executable and cmake build them twice.
The build time this way is double.
Can I do better?
What I have tried:
Have an OBJECT library and then use the *.obj files as input of both test and application.
But the problem is that this "objects" library has some dependencies, cpprestsdk, boost and others... I'm unable to set correctly the include dir for this target library :(
You can add a library target and link both your main executable and test code with that library. That way the library is built once and used many times.

Add CMake project as subproject in CMake project in Qt Creator

I have a directory layout like the following
projectA/
|-- CMakeLists.txt
|-- src/
|-- main.cpp
projectB/
|-- CMakeLists.txt
|-- src/
|-- file1.cpp
|-- file1.hpp
|-- file2.hpp
|-- main.cpp
|-- third_party/
|-- include
|-- lib1
I opened both project successfully in Qt Creator (using Ctrl+O and open the CMakeLists.txt file) and they're are able to build and run independently.
I need to gain access to file1.Xpp and file2.hpp from projectA. Is there a way in Qt Creator to add projectB as a subproject in projectA? And One might keep in mind that file1.Xpp and file2.hpp might depend on the third party library.
Using Ctrl+N -> Other Project -> Subdirs Project I can add a subproject, but only an empty one, if I'm not mistaken.
No, you can't add a CMake subject as a sub project.
Sub project is based of qmake.

How to add project local static or dynamic libraries in CMake?

I am trying to learn OpenGL and would like to set up my build environment with cmake. I will use GLEW (OpenGL Extension Wrangler) and freeglut. However there is one problem... Since I am an absolute beginner to "project management" in C++ and cmake I am having hard time pointing to static libraries. I can understand C++ code but compeletly new to C++ based project build systems.
I am just simply trying to generate a Visual Studio 2015 project. My question is: How can show my static libraries to cmake. My project folder structure:
build # Folder where I would like cmake generated files to be generated in this directory.
include
|-- GL
| |-- freeglut.h
| |-- freeglut_ext.h
| |-- freeglut_std.h
| |-- glut.h
|-- glew
| |-- eglew.h
| |-- glew.h
| |-- glxew.h
| |-- wglew.h
lib
|-- freeglut.lib
|-- freeglut_static.lib
|-- glew32.lib
|-- glew32s.lib
src
|-- main.cpp
CMakeLists.txt
My CMakeLists.txt file is as following:
cmake_minimum_required(VERSION 2.8)
project(sb7application)
find_package(OpenGL REQUIRED)
find_library(LINK_LIBS NAMES freeglut freeglut_static glew32 glew32s PATHS lib)
include_directories(include)
file(GLOB SOURCES "src/*.cpp")
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${OPENGL_LIBRARY})
Here, basicly what I want to do is to ask CMake to link static libraries in the lib folder. However this cmake script doesn't add the Linker input configuration to my visual studio project settings. For example, if I open the generated visual studio project and go to Properties > Linker of the project and add this lib directory to additional library directories and specify the libraries (.libs) in Properties > Linker > Input section, it compiles successfuly. Otherwise, it gives a linkage error saying something like '__imp_glewInit()' cannot be found.
Yeah, how can I show this lib directory and its contents as my static libraries to be linked? If you can explain like you explain to a child and explain each step in detail, I would be greatly appriciated.

Include header files from static library with CMake

I have a problem building a CMake project with a static library.
My project strucutre looks like that:
Foo/
|-- CMakeLists.txt
|-- lib/
|-- CMakeLists.txt
|-- libA/
|-- CMakeLists.txt
|-- libA.cpp
|-- libA.h
|-- libAB.h
|-- src/
|-- CMakeLists.txt
|-- main.cpp
|-- srcDirA/
|-- CMakeLists.txt
|-- srcA.h
|-- srcDirB/
|-- CMakeLists.txt
|-- srcB.cpp
|-- srcB.h
And the */CMakeLists.txt look like that:
Foo/CMakeLists.txt:
cmake_minimum_required(VERSION 3.5.1)
project(FOO)
set(CMAKE_CXX_STANDARD 11)
add_subdirectory(lib)
add_subdirectory(src)
Foo/lib/CMakeLists.txt:
add_subdirectory(libA)
Foo/lib/libA/CMakeLists.txt:
add_library (staticLibA STATIC libA.cpp)
Foo/src/CMakeLists.txt:
add_subdirectory(srcDirA)
add_subdirectory(srcDirB)
include_directories(".")
add_executable(foo main.cpp)
target_link_libraries(foo LINK_PUBLIC libA)
Foo/src/srcDirA/CMakeLists.txt is empty
Foo/src/srcDirB/CMakeLists.txt is empty
Now I am trying to include the header from my static library into my main project like this:
Foo/src/main.cpp:
#include "srcDirB/srcB.h"
#include "libA/libA.h"
int main() {
//...
return 0;
}
If I try to build this with CMake, libA is generated but I am getting a fatal error:
libA/libA.h: No such file or directory.
Does anyone know what I am doing wrong? Do I have to create a ProjectConfig.cmake file?
You don't need to create any Config files; these are for importing 3rd-party projects.
Since you're using CMake >= 3.5.1, you can esaily specify usage requirements for your libraries. Usage requirements are things like flags or include directories which clients need to build with the library.
So in Foo/lib/libA/CMakeLists.txt:, you'll do this:
add_library (staticLibA STATIC libA.cpp)
target_include_directories(staticLibA INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/..)
Or, if you want the same include directory to apply to libA itself (which is likely), use PUBLIC instead of INTERFACE.
That's all you really need to do. However, given the modern CMake you're using, you should replace your use of the legacy keyword LINK_PUBLIC with its modern equivalent PUBLIC.
Also, since you mention both CMakeLists in .../srcDir* are empty, why have them there in the first place? You can easily get rid of both them and the related add_subdirectory calls.