Compiled files in cmake - cmake

I Have configured a list of folders which will be considered for a build in a CMAKE file.But inside those folders there are few source file which will not taken for compilation while build.
How can I generate the list of files( C and C++ Source files) that are only considered for compilation for build using CMAKE.?

If you have multiple subfolders, you can add them by add_subdirectory and modify the CMakeLists.txt in the subfolders by accessing the ${SOURCE_FILES} variable in the parent scope by
SET(SOURCE_FILES ${SOURCE_FILES}
subFolder/yetAnotherFile.cpp
PARENT_SCOPE
)
In the main folder (the folder that includes the subfolder), you add the following to the CMakeLists.txt
SET(SOURCE_FILES main.cpp)
add_subdirectory(subFolder/
add_executable(program ${SOURCE_FILES})

Related

CMake copy dll transitively

Basically I want CMake to copy dependency's dll to the same directory of the executable. Suppose I have the following directory structure:
my-project/
CMakeLists.txt
lib/
CMakeLists.txt
... # Some source files
app/
CMakeLists.txt
... # Some source files
The library lib depends on some third party dll, say foo.dll. The executable in app, say app.exe, depends on lib.
I've written a FindFOO.cmake to make the third party library foo.dll an imported target named foo.
Now when I compile app, in order to run the executable, foo.dll is required to be in the same directory as app.exe. How can this be achieved automatically with cmake? And what if I want to use CPack to package the application into an installer?
CMAKE_RUNTIME_OUTPUT_DIRECTORY is your friend.
If this variable is created before creating some target, if the target is RUNTIME, it will define where the output of the target will be placed.
In your case, it can be used to force foo.dll and app.exe to be in the same folder. Your root CMakeLists.txt should look like this:
cmake_minimum_required(VERSION 3.15)
project(foo_and_app)
# app.exe and foo.dll will be in bin subfolder of build dir
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_subdirectory(lib)
add_subdirectory(app)
#not connected to placement, but only to package creation
include(CPack)
It should be noted that this variable is used to initialize the properties of the targets added, meaning that everything may also be achieved by directly manipulating appropriate target properties.
Regarding packaging, what you ask is possible, regardless of the placement of runtime targets, by using install cmake statement. In lib/CMakeLists.txt you should add something like this:
# suppose that the target named `foo`,
# i.e. it is added by add_library(foo SHARED .....)
install(TARGETS foo
RUNTIME DESTINATION bin
)
same should be done for app/CMakeLists.txt:
# suppose that the target named `app`,
# i.e. it is added by add_executable(app .....)
install(TARGETS app
RUNTIME DESTINATION bin
)
If you have these install statements, the final destination will be bin folder within the chosen install folder.
In the end, here are the links for CMake documentation describing:
CMAKE_RUNTIME_OUTPUT_DIRECTORY variable
RUNTIME cmake targets
install(TARGETS ...)

Best way to add include directories of root project to a subdirectory in CMake

I have a project with a CMakeLists.txt at the root, which includes a project in a subdirectory test/ using add_subdirectory with the flag EXCLUDE_FROM_ALL. The tests need all of the include directories of the parent project. What would be the most elegant way to do this?
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")
PROJECT(autoffi CXX)
SET(CMAKE_CXX_STANDARD 11)
SET(AutoFFI_VERSION_MAJOR 0)
SET(AutoFFI_VERSION_MINOR 1)
SET(Boost_USE_STATIC_LIBS OFF)
FIND_PACKAGE(BOOST 1.50 COMPONENTS system filesystem REQUIRED)
FIND_PACKAGE(LLVM 3.9 REQUIRED CONFIG)
ADD_DEFINITIONS(${LLVM_DEFINITIONS})
FIND_PACKAGE(Clang REQUIRED)
CONFIGURE_FILE(
"${PROJECT_SOURCE_DIR}/include/env.h.in"
#"${PROJECT_BINARY_DIR}/include/env.h"
"${PROJECT_SOURCE_DIR}/include/env.h" # added to VCS
)
INCLUDE_DIRECTORIES(
#"${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/include"
"${CLANG_INCLUDE_DIRS}"
"${Boost_INCLUDE_DIRS}"
)
# The C++ interface
ADD_LIBRARY(autoffiCore src/Type.cpp)
# FIXME: boost package finder seems to be broken
TARGET_LINK_LIBRARIES(autoffiCore boost_filesystem boost_system)
ADD_LIBRARY(autoffiBin src/BinFormat.cpp)
TARGET_LINK_LIBRARIES(autoffiBin autoffiCore)
ADD_LIBRARY(autoffiClang src/ClangEngine.cpp)
llvm_map_components_to_libnames(llvm_libs all)
TARGET_LINK_LIBRARIES(autoffiClang autoffiCore ${llvm_libs} ${CLANG_LIBS})
# The C interface
ADD_LIBRARY(autoffi src/PrettyPrinter.cpp src/libautoffi.cpp)
TARGET_LINK_LIBRARIES(autoffi autoffiBin autoffiClang)
set_target_properties(autoffiCore autoffiBin autoffiClang autoffi PROPERTIES DEFINE_SYMBOL BUILDING_SHARED)
# CLI Tools
ADD_EXECUTABLE(afdump src/dump.cpp src/PrettyPrinter.cpp)
TARGET_LINK_LIBRARIES(afdump autoffiBin)
ADD_EXECUTABLE(afconvert src/convert.cpp)
TARGET_LINK_LIBRARIES(afconvert autoffiBin)
ADD_EXECUTABLE(afcompile src/tooling.cpp src/PrettyPrinter.cpp)
TARGET_LINK_LIBRARIES(afcompile autoffiClang ${CLANG_LIBS} autoffiBin)
# Testing
ENABLE_TESTING()
ADD_TEST(headerASTDump afcompile test/assets/basic.h)
test/CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
project("AutoFFI Tests")
SET(CMAKE_CXX_STANDARD 11)
SET(GTEST_ROOT "${CMAKE_CURRENT_LIST_DIR}/gtest")
find_package(GTest REQUIRED)
INCLUDE_DIRECTORIES(${AUTOFFI_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS})
ADD_EXECUTABLE(autoffiTest libautoffi.cpp core.cpp formats.cpp clang.cpp)
TARGET_LINK_LIBRARIES(autoffiTest ${GTEST_BOTH_LIBRARIES})
SET_TARGET_PROPERTIES(autoffiTest PROPERTIES OUTPUT_NAME runtests)
You are keeping your main directory and your subdirectory test in completely separated projects. I suppose you are building test by invoking separately cmake and make a second time. No surprise that the include_directories of your main project as no impact on the test project.
You mention the command add_subdirectory, (that should be used to include test in from your main directory) but you are actually not using it...
If you're using include_directories() to add dirs, those should propagate down into targets in the test subdir. Beware though that relative paths are relative to the current source dir:
include_directories: Add include directories to the build.
include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
Add the given directories to those the compiler uses to search for include files. Relative paths are interpreted as relative to the current source directory.
cmake docs

how to use CMake file (GLOB SRCS *. ) with a build directory

this is my current CMakeLists.txt file
cmake_minimum_required(VERSION 3.3)
set(CMAKE_C_FLAGS " -Wall -g ")
project( bmi )
file( GLOB SRCS *.cpp *.h )
add_executable( bmi ${SRCS})
This builds from my source directory, but I have to clean up all the extra files after. My question is how do I build this from a build directory if all my source files are in the same source directory?
thanks
If you really need to use file(GLOB …), this CMakeLists.txt should work :
cmake_minimum_required(VERSION 3.3)
project(bmi)
add_definitions("-Wall" "-g")
include_directories(${PROJECT_SOURCE_DIR})
file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/*.cpp)
add_executable(bmi ${SRC_FILES})
In this case you have to launch cmake from your build directory every time you add or delete a source file :
cmake <your_source_dir> -G <your_build_generator>
As Phil reminds, CMake documentation doesn't recommend this use of GLOB. But there are some exceptions. You'll get more information on this post.
If you don't meet those exceptions, you'd rather list your source files than use GLOB :
set(SRC_FILES ${PROJECT_SOURCE_DIR}/main.cpp
${PROJECT_SOURCE_DIR}/bmi.cpp
… )
NB : if you have #include of your .h files in .cpp files, I don't see any reason to put them in add_executable, you just need to specify include directory with include_directories.
Cmake used to only update the list of source files if CMakeLists.txt was changed since the last cmake run or if cmake was used to configure the project again.
In cmake 3.11.0 recursive search and automatic re-configuration on adding or deleting source files was added. Since then you can use the following snippet:
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.11.0")
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS *.cpp *.h)
else()
file(GLOB SOURCE_FILES *.cpp *.h */*.h */*.cpp)
endif()
The file() command after the else() provides at least a bit of backwards compatibility: It still searches for source files in the current folder and its direct subfolders. But it doesn't automatically recognize if there are new files or old files have been deleted.
Note that VERSION_GREATER_EQUAL is only available in cmake >= 3.7

How can I make a CMakeList.txt belong to certain target or a folder?

I give the following example to illustrate my question. The projects have the following structure:
CMakeLists.txt
Dir1
Dir2
Dir3
In the CMakeLists.txt, I have the following definitions:
macro(obtain_sublist result _curdir)
set(curdir ${${_curdir}})
FILE(GLOB children RELATIVE ${curdir} ${curdir}/*)
SET(dirlist "")
FOREACH(child ${children})
IF(IS_DIRECTORY ${curdir}/${child})
LIST(APPEND dirlist ${child})
ENDIF()
ENDFOREACH()
SET(${result} ${dirlist})
endmacro()
set(curDir ${CMAKE_CURRENT_SOURCE_DIR})
obtain_sublist(subdir curDir)
foreach(var ${subdir})
add_subdirectory(${var})
endforeach()
Within each subdirectories (Dir1, Dir2 and Dir3) targets are built. When the project was built with Visual Studio, I can clearly observe that each target as well as its corresponding CMakeLists.txt, which is used to create the target. However, the top CMakeLists.txt in this example is unseen in the project as it does not create any target. Is there a way to include this CMakeLists.txt in the project? If possible, can I put it in a certain folder? Thanks.
It should already appear in the ALL_BUILD target I think.
If you want, you can create a custom target just to hold it. In the top-level CMakeLists.txt:
add_custom_target(CMakeFiles SOURCES ${CMAKE_SOURCE_DIR}/CMakeLists.txt)
Or you could add it to an existing target in one or more or the subdirs. So, in a subdir CMakeLists.txt you could add:
add_executable(Dir1 dir1.cpp ${CMAKE_SOURCE_DIR}/CMakeLists.txt)
You can create sub-folders of the target in the VS solution (which need not relate to actual filesystem folders) by using source_group:
source_group("root" FILES ${CMAKE_SOURCE_DIR}/CMakeLists.txt)

Cmake - How to build a project separated in different subfolders

I am trying to build a big project with CMake but I struggle on how to write the CMakeList.txt file.
My project is separated in different folders each containing a set of .hpp and .cpp files more or less related together as follows:
root
- memory
-- Memory.cpp
-- Memory.hpp
-- MemoryManager.hpp
-- MemoryManager.cpp
-- CMakeLists.txt
- tools
-- Array.cpp
-- Array.hpp
-- CMakeLists.txt
- main.cpp
- CMakeLists.txt
I would like to build all the files together to an executable. I don't want to build libraries in each subfolder as I don't see any good reason to do it.
I would like also to avoid putting a single big list of all source files in the ADD_EXECUTABLE command of the CMakeLists.txt file located at the root of the project.
Do you have any idea of how to set this up correctly ?
Cheers,
M.
You can use the GLOB function, such as:
file (GLOB _my_sources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
memory/*.cpp tools/*.cpp main.cpp)
add_executable (myprogbin ${_my_sources})
set_target_properties (myprogbin PROPERTIES OUTPUT_NAME myprog)
See http://cmake.org/cmake/help/cmake-2-8-docs.html#command:file for reference