# set() / PARENT\_SCOPE

**URL:** <https://discourse.cmake.org/t/set-parent-scope/9512>\
**Category:** Code\
**Created:** [November 27, 2023, 12:05pm UTC](https://discourse.cmake.org/t/set-parent-scope/9512 "2023-11-27T12:05:24Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Oodini](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/o/db5fbb/32.png) [@Oodini](https://discourse.cmake.org/u/Oodini)\
**Post date:** [November 27, 2023, 12:05pm UTC](https://discourse.cmake.org/t/set-parent-scope/9512/1 "2023-11-27T12:05:24Z")

</div>

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 :

```auto
├── 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`

```auto
add_subdirectory(MyLib)
message(${LIB_PROJECT_NAME})

```

But then I get the message :

```auto
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 :

```auto
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**.

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [November 27, 2023, 12:32pm UTC](https://discourse.cmake.org/t/set-parent-scope/9512/2 "2023-11-27T12:32:46Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Oodini](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/o/db5fbb/32.png) [@Oodini](https://discourse.cmake.org/u/Oodini)\
**Post date:** [November 27, 2023, 12:42pm UTC](https://discourse.cmake.org/t/set-parent-scope/9512/3 "2023-11-27T12:42:39Z")

</div>

Do you mean doing :

```auto
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.

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [November 27, 2023, 8:41pm UTC](https://discourse.cmake.org/t/set-parent-scope/9512/4 "2023-11-27T20:41:51Z")

</div>

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.
