Home > OS >  why add_subdirectory() command did not work for my CMakeLists.txt?
why add_subdirectory() command did not work for my CMakeLists.txt?

Time:07-20

I have a simple exercise on cmake with following file tree:

proj01/
      include/
             functions.h
      src/
         main.cpp
         functions.cpp
         CMakeLists.txt
      CMakeLists.txt        
      README

My project CMakeLists.txt is like this:

  cmake_minimum_required(VERSION 3.21)

  project (test01)

  add_subdirectory(src)
  set(SOURCES
       main.cpp
       functions.cpp
   )
    
  add_executable(myProgram ${SOURCES})

and when I tried to build, I got error:

# Error! 

CMake Error at CMakeLists.txt:18 (add_executable):
  Cannot find source file:
    main.cpp

CMake Error at CMakeLists.txt:18 (add_executable):
  No SOURCES given to target: myProgram

If I change the project CMakeLists.txt by giving the absolute path(relative to the project), it worked!

#add_subdirectory(src)
set(SOURCES
   src/main.cpp
   src/functions.cpp
)

add_executable(myProgram ${SOURCES})

When there is multiple source files in multiple subdirectories, it would be better to explicitly list all source files including their paths as what is done with my working version of the CMakeLists.txt.

Spent hours to search for command add_subdirectories(), this, this, and this, but no luck. The closest one would be this question, but there is no solution for that question so far.

What did I miss with my add_subdirectory(src) in this simple specific scenario? Any help is appreciated.

CodePudding user response:

add_subdirectory(src) results in cmake parsing src/CMakeLists.txt creating a new directory src in the build tree for building the part of the project in this cmake file.

It doesn't result in you being able to use shorter paths in the CMakeLists.txt file containing the add_subdirectory command.

If you move the target to src/CMakeLists.txt you could use the shorter paths:

CMakeLists.txt

cmake_minimum_required(VERSION 3.21)

project (test01)

add_subdirectory(src) # add src/CMakeLists.txt to this project

src/CMakeLists.txt

cmake_minimum_required(VERSION 3.21)

set(SOURCES
     main.cpp
     functions.cpp
 )
    
add_executable(myProgram ${SOURCES})

Personally I'd avoid adding an additional CMakeLists.txt file just to shorten the paths. It's easy to remove the duplication of the src dir, if that's what you're worried about.

set(SOURCES
       main.cpp
       functions.cpp
   )

list(TRANSFORM SOURCES PREPEND "src/")

or

function(subdir_files VAR DIR FILE1)
    set(FILES)
    foreach(SRC IN ITEMS ${FILE1} ${ARGN})
        list(APPEND FILES ${DIR}/${SRC})
    endforeach()
    set(${VAR} ${FILES} PARENT_SCOPE)
endfunction()

subdir_files(SOURCES src
       main.cpp
       functions.cpp
   )
  • Related