set() / PARENT_SCOPE

Hello,

I am working on a file structure with several CMakeLists.txt.

EDIT : Does it make sense to have this deep structure ? Visual Studio seems not to be able to mimic it in Solution / projects (tests wouldn’t be nested in the lib) ? If not, maybe I shoud review my structure before submitting my question.

I must do a .exe, a .lib, and tests associated to the .lib.

So here is the file structure :

├── MyEcutable
│   ├── CMakeLists.txt
│   └── src
│       ├── CMakeLists.txt
│       ├── x.h
│       ├── x.cpp
│       ├── y.h
│       ├── y.cpp
│       └── main.cpp
├── MyLibrary
│   ├── CMakeLists.txt
│   ├── include
│   │   └── a.h
│   ├── src
│   │   ├── CMakeLists.txt
│   │   ├── a.h
│   │   └── a.cpp
│   └── test
│       ├── CMakeLists.txt
│       └── test_a.cpp
└── CMakeLists.txt

As I need to link the test to the library, in MyLibrary/CMakeLists.txt, I did :
set(LIB_PROJECT_NAME "MyLib" PARENT_SCOPE)

The purpose was to make ${LIB_PROJECT_NAME} visible in ./CMakeLists.txt

add_subdirectory(MyLib)
message(${LIB_PROJECT_NAME})

But then I get the message :

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

The concerned line is the second instruction in :

add_library(${LIB_PROJECT_NAME} STATIC)
target_sources(${LIB_PROJECT_NAME}
               PRIVATE
				   a.cpp
			   PUBLIC
				   ../include/a.h)

I have no error if I remove PARENT_SCOPE.

I recommend doing PARENT_SCOPE settings at the end of the file. It has a non-obvious (but documented) behavior of taking the value of the variable in the parent scope and setting it in the current scope. Since it is not set there, it basically unsets it in the current scope. Since it is empty, target_sources is seeing the first argument as PRIVATE, hence the error (you also made a target named STATIC on the previous line).

Do you mean doing :

set(LIB_PROJECT_NAME "RectalWallDetectionLib")                 [beginning of file]
...
set(LIB_PROJECT_NAME "RectalWallDetectionLib" PARENT_SCOPE)    [end of file]

If so, yes, it does work. Thanks !

I intend now to use it in MyLibrary/test/CMakeLists.txt, inder to link the library to the test executable.
I hope it is the right way/practice.

I’d recommend not using a LIB_PROJECT_NAME variable at all. Write the name of the target directly, don’t try to carry it around in a variable. You don’t gain anything by putting it in a variable, and it actually makes it harder in larger projects where you may want to search (grep) for places where a target is referenced.

1 Like