Meson project: can I have part of the source located elsewhere? - c++

In a Meson project, how can I compile files (i.e. not just headers) located in an directory which is not in my project tree?
E.g.:
MyProj/
src/
meson.build
ExternalCode/
src/
file1.h
file1.cpp
include_directories is just for headers...
If I use ".." in the files path, I get this error:
meson.build:10:0: ERROR: Subdir contains ..

If you want to build ExternalCode as a part of your project, then I recommend fetch somehow this directory inside your project, e.g. using symbolic link and place meson.build file alongside. So, your project layout will look as:
MyProj/
meson.build
src/
meson.build
external/
ExternalCode -> link to ...
meson.build
Then, make aware meson of all sub-directories in the project placing this in top level meson.build file:
subdir('src')
subdir('external')

yes but the external file must be picked up in the following way:
e.g.
source = files(file1.cpp)
put in meson.build inside
ExternalCode/src
folder

Related

Project Linking and Compiling files

I want to start building a project and I have the following folder structure:
lib
|---class1.cpp
|---class1.hpp
src
|---main.cpp
I have the MinGW compiler and I don't know how to compile all .cpp files. I know the command g++ *.cpp -o main for compiling all the files, but works only for files in the same folder.
Should I move all my files to the src folder? Should I change the project structure?
Also, I'm really doubtful if I should use CMake or not.
FINAL:
I decided to go with CMake which made my life easier.
For a barebones project, your structure is fine. Just add the following CMakeLists.txt file to the root of your directory:
cmake_minimum_required(VERSION 3.5)
# Given your project a descriptive name
project(cool_project)
# CHoose whatever standard you want here... 11, 14, 17, ...
set(CMAKE_CXX_STANDARD 14)
# The first entry is the name of the target (a.k.a. the executable that will be built)
# every entry after that should be the path to the cpp files that need to be built
add_executable(cool_exe src/main.cpp lib/class1.cpp)
# Tell the compiler where the header files are
target_link_libraries(cool_exe PRIVATE lib)
Your directory should now look like
CMakeLists.txt
lib
|---class1.cpp
|---class1.hpp
src
|---main.cpp
Then to build the project, you will typically
Make a folder where you build everything (often called build, but it's up to you). Now the directory looks like
CMakeLists.txt
lib
|---class1.cpp
|---class1.hpp
src
|---main.cpp
build
Go into the build folder and on the command like, configure your project with the command cmake .. (just to reiterate... this needs to be done from inside the build folder).
Build your project with the make command (again from inside the build folder).
After that, you should have an executable called cool_exe in the build folder.

using cmake to make header files descendants of the project's source directory

As in Google C++ Style Guide is mentioned all of a project's header files should be listed as descendants of the project's source directory without use of UNIX directory shortcuts . (the current directory) or .. (the parent directory). How can I do that in my project that is shortly described below.
My project directory hierarchy is like this:
GraphicsEngine
header_files.h
source_files.cc
CMakeLists.txt (1)
Light
CMakeLists.txt (2)
header_files.h
source_files.cc
Camera
CMakeLists.txt (3)
header_files.h
source_files.cc
Core
CMakeLists.txt (4)
header_files.h
source_files.cc
These are contents of CMakeLists.txt files:
CMakeLists.txt (1)
add_library(GraphicsEngineLib source_files.cc)
target_link_libraries(GraphicsEngineLib LightLib CameraLib CoreLib)
add_subdirectory(Light)
add_subdirectory(Camera)
add_subdirectory(Core)
CMakeLists.txt (2)
add_library(LightLib source_files.cc)
CMakeLists.txt (3)
add_library(CameraLib source_files.cc)
CMakeLists.txt (4)
add_library(CoreLib source_files.cc)
Now when for example I want to include header files from Camera folder in to files in Core folder, I have to use ../Camera/header_file.h but I want to use GraphicsEngine/Camera/header_file.h. How can I do this?
What I have done in the past is to set this in the top level CMakeLists.txt (which should be in your GraphicsEngine directory):
SET(PROJECT_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/..")
INCLUDE_DIRECTORIES(
${PROJECT_ROOT}
)
where according to this, CMAKE_CURRENT_SOURCE_DIR is
this is the directory where the currently processed CMakeLists.txt is located in
Note that by defining Project_Root in this way, your GraphicsEngine project can also #include headers from sister projects to GraphicsEngine.
Hope this helps.

CMake doesn't include header directory of submodule A within submodule B

I have a CMake project that looks like this:
project/
CMakeLists.txt
subprojectA/
CMakeLists.txt
include/
headerA.hpp
src/
libraryA.cpp
subprojectB/
CMakeLists.txt
src/
mainB.cpp
The "library" subproject, A, is compiled as a static library, becoming libsubprojectA.a. The "main" project, B, is compiled as a binary and depends on the library. mainB.cpp includes a reference to headerA.hpp.
Here is subprojectA/CMakeLists.txt:
project(SubProjectA)
include_directories(include)
add_library(subprojectA STATIC src/libraryA.cpp)
set(${PROJECT_NAME}_INCLUDE_DIRS
${PROJECT_SOURCE_DIR}/include
CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
And here is subprojectB/CMakeLists.txt:
project(SubProjectB)
include_directories(${SubProjectA_INCLUDE_DIRS})
add_executable(mainBinary src/mainB.cpp)
target_link_libraries(mainBinary subprojectA)
The main Project CMakeLists.txt looks like:
project(Project)
add_subdirectory(subprojectB)
add_subdirectory(subprojectA)
Note that subprojectB, the main project, is listed before subprojectA.
Here's the problem. When I first run "cmake" on this project, ${SubProjectA_INCLUDE_DIRS} is not set within SubProjectB.
What I think is happening is that the CMakeLists for SubProjectB loads first, when ${SubProjectA_INCLUDE_DIRS} has not yet been set. It sets its own include path to an empty string as a result. However, even though libsubprojectA.a gets built successfully before mainBinary, the include path was already set empty beforehand. As a result, I get this error when trying to make mainBinary:
subprojectB/src/mainB.cpp:1:23: fatal error: headerA.hpp: No such file or directory
#include "headerA.hpp"
^
It's a workaround to put subprojectA before subprojectB in the main Project CMakeLists in the declarative world of CMake. What I really want is to know the proper way to indicate to CMake that the include_directories(${SubProjectA_INCLUDE_DIRS}) line depends on the definitions that exist inside SubProjectA's CMakeLists. Is there a better way to do this?
If you want to express that include directory subprojectA/include is an interface of the library subprojectA, attach this property to the target with target_include_directories command:
subprojectA/CMakeLists.txt:
project(SubProjectA)
add_library(subprojectA STATIC src/libraryA.cpp)
# PUBLIC adds both:
# 1) include directories for compile library and
# 2) include directories for library's interface
target_include_directories(subprojectA PUBLIC include)
So any executable(or other library) which linked with subprojectA will have this include directory automatically:
subprojectB/CMakeLists.txt:
project(SubProjectB)
add_executable(mainBinary src/mainB.cpp)
target_link_libraries(mainBinary subprojectA)
Of course, for use last command properly you need to process directory with library before one with executable:
CMakeLists.txt:
project(Project)
add_subdirectory(subprojectA)
add_subdirectory(subprojectB)

Building a cmake project with multiple directories

I have been given some C++ which I want to use in my project. This code comes with its own CMakeLists.txt file. To keep things neat, I want to make a new directory foo in my main project directory, and put this code and the CMakeLists.txt file in that directory. What I now want to know, is how do I edit the CMakeLists.txt file of my own project, to include all the source files from this other project?
Normally, I use file(glob SOURCES *.cpp) to create a list of all source files. Then, I would create the executable by using add_executable(${PROJECT_NAME} ${SOURCES}). However, how do I tell SOURCES to also include all the source files in the foo directory?
Now, if I use add_subdirectory(foo) in my main CMakeLists.txt file, then I believe this will search directory foo for a CMakeLists.txt file, and effectively add this to the main CMakeLists.txt file in my project. Is this correct? How can I extend this to including all the source files in this directory?
Thanks!

Have CMake recursively scan folders?

How do I set up CMake to recursively scan a given directory and determine the list of source files?
My project is a shared library. I have a folder structure similar to this:
/
src/ # Source files in an arbitrary tree
include/ # Headers, tree mirrors that of the src/ folder
examples/ # Executable code examples that link against the library
CMakeLists.txt
I want CMake to recursively scan src and include and determine the list of source and header files in my project, regardless of the directory structure. I also want to avoid:
Polluting the src/ and include/ directories with endless CMakeLists.txt files
Having to change and adapt the scripts every time I change my folder structure
It is fine for each example to have their own build script, however.
CMake provides the following command for recursive files globing:
file(GLOB_RECURSE variable [RELATIVE path]
[FOLLOW_SYMLINKS] [globbing expressions]...)
Command documentation: http://www.cmake.org/cmake/help/v2.8.8/cmake.html#command:file