We use similar layout in a set of components, but in order to do that we just 
store library interface headers in <lib-name>/include/<lib-name> directory. And 
layout of library directory is the following:
src/  - internal headers and implementation
include/ - external headers
CMakeLists.txt

Then you can define the following to expose the directory for clients of the 
library within the same CMake project:
target_include_directories(<lib-name>
    PRIVATE src
    PUBLIC include
)


Another way to achieve that is to expose library's parent directory as include 
interface. That's a case if all your sources, external and internal headers are 
stored under the library directory:
get_filename_component(PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)

target_include_directories(<lib-name>
    INTEFACE ${PARENT_DIR}
)

As downside, that would make all headers (even internal) visible to the clients 
of the library.


If you have two separate CMake projects (i.e. two git repos) you can change 
layout of the headers on install step without changing anything in source tree.
e.g. we have external and internal headers in src directory:
target_include_directories(<lib-name>
    PRIVATE "$<BUILD_INTERFACE:src>"
    INTERFACE "$<INSTALL_INTERFACE:include/<lib-name>>"
)

install (FILES src/foo.h
                       src/bar.h
           DESTINATION include/<lib-name>
           COMPONENT devel
)


In all the cases, I assume usage requirements model (target_link_libraries) is 
used for consumption of the library.

-Roman

> 20 янв. 2015 г., в 4:14, Chris Johnson <cxjohn...@gmail.com> написал(а):
> 
> A common and useful method for avoiding name conflicts and keeping files 
> well-organized is to place them in a subdirectory unique to the library.  For 
> example, the libraries for Graphviz and Postgres often install their API 
> header files in directories named <install-prefix>/include/graphviz and 
> <install-prefix>/include/libpq.  So on my local development system, these 
> libraries' API header files are in /usr/local/include/graphviz/*.h and 
> /usr/local/include/libpq/*.h.
> 
> This is the convention that we use for our internal projects as well.
> 
> C++ code which needs to include these files by necessity must name that 
> subdirectory.  For example, to use Postgres's API defined in libpq-fs.h, the 
> C++ code must look like this:
> 
> #include <libpq/libpq-fs.h>
> 
> We do the same for our internal libraries, for example, to use the 
> "projectlib" library from some program, the code would resemble:
> 
> #include <projectlib/foo.h>
> 
> In the library itself, however, the code is like this:
> 
> foo.h:
> -----
> class Foo {
> public:
>     Foo();
> };
> 
> foo.cpp
> -------
> #include "foo.h"
> 
> Foo::Foo() {
>  // constructor code
> }
> // etc.
> 
> That is, note that the header and source files are in the SAME directory.
> 
> 
> CMake does not handle this well when trying to compile a program using the 
> library.  CMake wants to look in the source directory or the build directory 
> for the header file, and those directory paths do not have the "projectlib" 
> prefix which is what the source code for the program expects (#include 
> <projectlib/foo.h>).
> 
> I've kludged around this by adding a function which does some ugly directory 
> creation in the build directory and then copies the headers to where the 
> source expects to find them.
> 
> But I think there's something about CMake I am not understanding correctly, 
> or a feature I should be using that I am unaware of, in order to make this 
> all work without writing code in my CMakeLists.txt files to copy source files 
> to expected places.  This library file layout for headers and source is very 
> common in the Unix world, and we've modeled our largish (500 directories, 
> dozens of libraries) project on it.
> 
> Is there something about CMake I need to learn to make this work more cleanly?
> 
> 
> Thanks,
> ..chris
> 
> 
> 
> 
> 
> 
> Most libraries correctly put their headers into ./include/<libdirname> 
>       39      # but CMake wants to look in the source or build dir, which 
> doesn't have 
>       40      # <libdirname> as a prefix. That prefix is used in the source 
> files in  
>       41      # their #include "libdirname/libheader.h" statements.  Headers 
> will not be 
>       42      # found with that prefix when obtained from the source or build 
> dir by CMake. 
> 
> -- 
> 
> Powered by www.kitware.com
> 
> Please keep messages on-topic and check the CMake FAQ at: 
> http://www.cmake.org/Wiki/CMake_FAQ
> 
> Kitware offers various services to support the CMake community. For more 
> information on each offering, please visit:
> 
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/training.html
> 
> Visit other Kitware open-source projects at 
> http://www.kitware.com/opensource/opensource.html
> 
> Follow this link to subscribe/unsubscribe:
> http://public.kitware.com/mailman/listinfo/cmake

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake

Reply via email to