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.

1
  • 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. Commented May 11, 2018 at 22:25

3 Answers 3

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
Sign up to request clarification or add additional context in comments.

2 Comments

It solved my problem. I am just wondering whether it contradicts the first part of the accepted answer here. stackoverflow.com/questions/25609692/…
Yes, my answer contradicts the referenced one. I have added a comment to that answer.
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

1 Comment

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.
0

None of the suggested answers worked for me.

This works:

add_executable(<executable_name> <source_file_name>)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.