in CMakeLists.txt, if I use
configure_file (
"${PROJECT_SOURCE_DIR}/libConfig.h.in"
"${PROJECT_SOURCE_DIR}/libConfig.h"
)
the file libConfig.h would be mixed with original source together, this would cause troubles in source code files management especially the source code has many folders and files.
but if I use
configure_file (
"${PROJECT_SOURCE_DIR}/libConfig.h.in"
"${PROJECT_BINARY_DIR}/libConfig.h"
)
I can keep the source code folder clean. But the trouble is: the cpp code can't find the header file libConfig.h to include. So I need to put the generated libConfig.h to INCLUDE_DIRECTORIES, then the compiler can find it.
I can find some solution here
CMake configure_file with out of source build
and the discussion mentioned target_include_directories
is better than include_directories
, and I tried.
The result is out of prediction. include_directories
works, the cpp file can find the header file libConfig.h; but target_include_directories
doesn't work, libConfig.h can't be found and included.
As we all know, include_directories
would ask all sub directories to add the include directory. This is not what we want, if we don't hope to add this into some sub directory, we can't adjust. And I hope target_include_directories
can work, but I don't know why it doesn't work.
if anybody knows why it doesn't work as my wish, please help me.
the following is the whole CMakeLists.txt, everybody can have a test.
cmake_minimum_required(VERSION 3.5)
project(mylib CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_library(${PROJECT_NAME}
SHARED
StringManipulator.cpp
)
configure_file (
"${PROJECT_SOURCE_DIR}/libConfig.h.in"
"${PROJECT_BINARY_DIR}/libConfig.h"
)
message("PROJECT_NAME = ${PROJECT_NAME}")
message("CMAKE_PROJECT_NAME = ${CMAKE_PROJECT_NAME}")
message("CMAKE_CURRENT_BINARY_DIR = ${CMAKE_CURRENT_BINARY_DIR}")
message("INCLUDE_DIRECTORIES = ${INCLUDE_DIRECTORIES}")
# because this lib would be integrated in some big programme, so ${CMAKE_CURRENT_BINARY_DIR} is used here
target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
# include_directories(${CMAKE_CURRENT_BINARY_DIR})
message("INCLUDE_DIRECTORIES = ${INCLUDE_DIRECTORIES}")
option (BOOST_ALGORITHM_STRING_SPLIT
"Use Boost Algorithm to split string"
ON
)
if (BOOST_ALGORITHM_STRING_SPLIT)
find_package(Boost)
endif (BOOST_ALGORITHM_STRING_SPLIT)
If you need a cpp file to test, please refer to
#include "libConfig.h"
#include <sstream>
#include <string>
#include <vector>
#include <regex>
#ifdef BOOST_ALGORITHM_STRING_SPLIT
#include <boost/algorithm/string.hpp>
#endif
#ifndef BOOST_ALGORITHM_STRING_SPLIT
std::vector<string> split(const string &str, const std::regex &re_delim)
{
std::sregex_token_iterator first{str.begin(), str.end(), re_delim, -1}, last;
return {first, last};
}
#endif
#ifdef BOOST_ALGORITHM_STRING_SPLIT
std::vector<std::string> split(const std::string &str, const std::string &delim)
{
std::vector<std::string> results;
boost::algorithm::split(results, str, boost::is_any_of(delim));
return results;
}
#endif
the file libConfig.h.in is very simple, too
#cmakedefine BOOST_ALGORITHM_STRING_SPLIT