user997112
user997112

Reputation: 30605

CMake "Cannot specify sources for target PROJECT_NAME which is not built by this project."

I am learning CMake but unfortunately most examples are either too simple, too complicated or the folder structure is different to what I'm designing.

I am getting an error but first I will explain the folder structure (please do critique):

MyProject
    bin
    build
    src
        ComponentA
            ObjectA.cpp
            CMakeLists.txt
        ComponentB
            ObjectB.cpp
            CMakeLists.txt
        CMakeLists.txt
        main.cpp
    CMakeLists.txt

I would like to be able to include some files using their absolute path, for example main.cpp might look like this:

#include <ComponentB/ObjectB.h>

int main()
{
    ComponentB cb(1, 2, 3);
}

but within a source file I'd like to include it's header using the relative path:

#include <ComponentB.h>

ComponentB::ComponentB(int a, int b, int c) : _ca(a, b){}

(if this causes problems I can include using absolute paths)

My CMakeLists files look like:

MyProject/CMakeLists.txt:

cmake_minimum_required(VERSION 3.9.1)
project(MyProject)
add_subdirectory(src)

MyProject/src/CMakeLists.txt:

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_ROOT_DIR}/bin)
add_executable(MyProject main.cpp)
add_subdirectory(ComponentA)
add_subdirectory(ComponentB)

MyProject/src/ComponentA/CMakeLists.txt:

target_sources(MyProject PUBLIC ComponentA.cpp)

MyProject/src/ComponentB/CMakeLists.txt:

target_sources(MyProject PUBLIC ComponentB.cpp)
target_include_directories(MyProject PUBLIC ComponentA) 

However when I do:

cd build
cmake ..

I get this this error:

CMake Error at src/ComponentA/CMakeLists.txt:2 (target_sources):
  Cannot specify sources for target "MyProject" which is not built by
  this project.

CMake Error at src/ComponentB/CMakeLists.txt:2 (target_sources):
  Cannot specify sources for target "MyProject" which is not built by
  this project.

CMake Error at src/ComponentB/CMakeLists.txt:3 (target_include_directories):
  Cannot specify include directories for target "MyProject" which is not
  built by this project.

Upvotes: 3

Views: 4639

Answers (1)

Alex Reinking
Alex Reinking

Reputation: 19816

The ability for target_sources to add source files via relative path to a target in a different directory was added in CMake 3.13. Since you have specified a minimum version of 3.9.1, this will simply not work.

The policy in question is CMP0076, which is documented as follows:

New in version 3.13.

The target_sources() command converts relative paths to absolute.

In CMake 3.13 and above, the target_sources() command now converts relative source file paths to absolute paths in the following cases:

  • Source files are added to the target's INTERFACE_SOURCES property.
  • The target's SOURCE_DIR property differs from CMAKE_CURRENT_SOURCE_DIR.

It is the second bullet point that applies here.

You really ought to use a newer version of CMake. Anything more than a few versions behind the newest (3.23) is plain masochism.

Upvotes: 1

Related Questions