5

I am trying to organize a C++ project which starts to have a lot of files. I would like to create two executables which share some source file using Cmake. I have found an interesting procedure here:

How to add source files in another folder

Below is my version of the thing

file(GLOB Common_sources RELATIVE "Common" "*cpp")
file(GLOB Mps_sources RELATIVE "Mps" "*.cpp")                 
file(GLOB Mss_sources RELATIVE "Mss" "*.cpp") 

add_executable(test_mss ${Common_sources} ${Mss_sources}) 
add_executable(test_mps ${Common_sources} ${Mps_sources})

But CMake complains

CMake Error at src/CMakeLists.txt:44 (add_executable):
add_executable called with incorrect number of arguments

CMake Error at src/CMakeLists.txt:45 (add_executable):
add_executable called with incorrect number of arguments

It says to look at CMakeOutput.log, but the file is really too long, I can not find useful information.

I checked the CMake documentation, it seems that it can take a second source as an additional argument. https://cmake.org/cmake/help/v3.0/command/add_executable.html

I would like to find the source of this bug. I have the feeling that I am missing something obvious here.

Raphael D.
  • 778
  • 2
  • 7
  • 18
  • Check your souces lists. If they are empty, then `add_executable` will fail. You may use something like `message ("Common ${Common_sources}")` to output your sources list. – Innokentiy Alaytsev May 11 '18 at 22:25

3 Answers3

5

The error you get is because source list, passed to add_executable, is actually empty.

Correct way for collect sources in Common/ subdirectory is:

file(GLOB Common_sources "Common/*.cpp")

In command file(GLOB) RELATIVE option doesn't specify search directory. Instead, it just tells CMake to generate relative paths instead of absolute:

If RELATIVE flag is specified, the results will be returned as relative paths to the given path.

Assuming

file(GLOB Common_sources "Common/*.cpp")
# gets: /<path-to-source>/Common/my_source.cpp

then (also note to absolute path in RELATIVE option)

file(GLOB Common_sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/Common" "Common/*.cpp")
# gets: my_source.cpp

and (when files are not under RELATIVE directory)

file(GLOB Common_sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/Mps" "Common/*.cpp")
# gets: ../Common/my_source.cpp
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • It solved my problem. I am just wondering whether it contradicts the first part of the accepted answer here. https://stackoverflow.com/questions/25609692/how-to-add-source-files-in-another-folder?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – Raphael D. May 12 '18 at 15:30
  • Yes, my answer contradicts the referenced one. I have added a [comment](https://stackoverflow.com/questions/25609692/how-to-add-source-files-in-another-folder#comment87626669_25610377) to that answer. – Tsyvarev May 12 '18 at 18:27
2

You have to quote the variables.

add_executable(test_mss "${Common_sources}" "${Mss_sources}")

Otherwise for an empty variable, CMake replaces the variable by nothing and the number of arguments seems to be wrong.

Similar problem: https://stackoverflow.com/a/39733128/2799037

usr1234567
  • 21,601
  • 16
  • 108
  • 128
  • 2
    Quoting a variable's dereference, when the variable can be empty, has a sence, but only when empty string is acceptable. In case of `add_executable` empty strings are not acceptable (name of source file cannot be empty). So quoting has no sence with `add_executable`. – Tsyvarev May 12 '18 at 08:56
0

None of the suggested answers worked for me.

This works:

add_executable(<executable_name> <source_file_name>)
Eric Aya
  • 69,473
  • 35
  • 181
  • 253