0

I have a CMakeLists.txt file for a library. It's pretty basic:

set(LIB_FILES source/first.cpp)

add_library(first ${LIB_FILES})

I put the files in a list because I will eventually be adding more source files to the library. The problem is that all of the files will be in the source directory. And I don't want to constantly have to repeat that.

I also don't want to use the GLOB pattern matching solution, because I want to have to edit the CMakeLists.txt file when I add a new file. That way, my build will re-build the build solution, and new files will correctly appear (as I understand it. I'm still new with CMake).

I tried adding a CMakeLists.txt file into the source directory itself, just to build the LIB_FILES list. That didn't work out very well. Variables in CMake are file scoped. And even when I broke scoping (with PARENT_SCOPE), I still had to prefix each file with the directory. So that gained nothing.

I don't want to put the actual library definition in the source directory, as that will generate all the build files in the source directory. And I don't want that. Also, I will need to include headers that aren't in or under the source directory.

My directory structure looks like this:

libroot (where the project build files should go)
\-source (where the source code is)
\-include (where the headers that the user of the library includes go)

So how do I tell CMake that all of the source files come from the source directory, so that I don't have to constantly spell it out?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982

2 Answers2

3

You could move the add_library call to your source/CMakeLists.txt also:

set(LIB_FILES first.cpp)
add_library(first ${LIB_FILES})

Then just use add_subdirectory in your top-level CMakeLists.txt:

add_subdirectory(source)
Fraser
  • 74,704
  • 20
  • 238
  • 215
  • I thought I mentioned that I didn't want to do that, but I guess I missed that case. The source files are in the `source` directory precisely because I *don't* want to put the build files in the source directory. Also, I have include files that won't be in the `source` directory or underneath it. – Nicol Bolas Jul 30 '13 at 01:45
  • 1
    OK. But with an [out-of-source build](http://www.cmake.org/Wiki/CMake_FAQ#Out-of-source_build_trees) (the recommended technique), the build files wouldn't be an issue. Also, now that I see your directory structure, it would be normal to include all the headers of the "include" folder in your `add_library` call so that they show up in IDEs like MSVC. In which case you'd probably be better with a couple of `macro`s as per @user1283078's answer. – Fraser Jul 30 '13 at 01:56
  • @NicolBolas This is the correct answer, or at least the correct way to operate. With CMake doing out-of-source builds is straightforward. – Antonio Jul 30 '13 at 06:57
  • @Antonio: "*With CMake doing out-of-source builds is straightforward.*" So, what you're saying is that I should rearrange the entire directory structure for my projects, just because I want to transition away from [an irregularly updated build system](http://industriousone.com/premake) into one that has reasonable support and updates? I don't think I'll be doing that. Just because you can do "out-of-source builds" doesn't mean you should *have* to. – Nicol Bolas Jul 30 '13 at 07:29
  • @NicolBolas Forgive me, but I cannot think of one benefit of in-source build, and you don't have to change anything in your directory structure, with CMake it comes for free – Antonio Jul 30 '13 at 07:59
  • @Antonio: "*you don't have to change anything in your directory structure*" Except that every directory with files must have a CMakeLists.txt file in it. And, as I understand the `add_library` command, that function creates a library build. Every time you call it, you get a new library. So with this method, each directory must be a single library. Therefore, the only way for me to not have to prefix either my headers or my source code is if all the header *and* source files are in the same directory as my CMakeLists.txt file. Which means that my directory structure *must be changed*. – Nicol Bolas Jul 30 '13 at 08:11
  • @NicolBolas You are not forced to add one CMakeLists.txt or one library per directory. Just a recent example http://stackoverflow.com/q/17934024/2436175 – Antonio Jul 30 '13 at 08:31
  • @Antonio: The person asking that question had to qualify his files with the directory names, which is exactly what I *want to avoid*. And your answer is exactly what I said above: making each subdirectory a static library, which is *also* not what I want. So I'm not seeing how this example helps me in any way to achieve what I want. – Nicol Bolas Jul 30 '13 at 09:06
2

you could use a simple macro for that

macro(AddSrc dst_var basepath_var)
    foreach(file ${ARGN})
        list(APPEND ${dst_var} ${basepath_var}/${file})
    endforeach()
endmacro()

set(MY_SRCFILES "")

AddSrc(MY_SRCFILES path/to/source
    foo.cpp
    bar.cpp
    whatever.cpp
)
user1283078
  • 2,006
  • 17
  • 17