0

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

Split a string using C++11

#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
  • 1
    "I hope `target_include_directories` can work, but I don't know why it doesn't work." - You are using INTERFACE keyword for this call, so it adds include directories only to the **users** of your library. For specifying include directories for compilation of the library itself use `PUBLIC` keyword. – Tsyvarev Oct 19 '22 at 14:47

0 Answers0