# Macros, target\_link\_library, target\_sources evaluation questions

**URL:** https://discourse.cmake.org/t/macros-target-link-library-target-sources-evaluation-questions/8279
**Category:** Code
**Created:** [June 7, 2023, 8:40pm UTC](https://discourse.cmake.org/t/macros-target-link-library-target-sources-evaluation-questions/8279 "2023-06-07T20:40:21Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![jwm](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jwm/32/654_2.png) [@jwm](https://discourse.cmake.org/u/jwm)
#### Post date: [June 7, 2023, 8:40pm UTC](https://discourse.cmake.org/t/macros-target-link-library-target-sources-evaluation-questions/8279/1 "2023-06-07T20:40:21Z")

</div>

I am developing a set of practices to facilitate commonality in our projects. One of them, to facilitate unit tests, is that for a given executable, all the sources except for “main” should be in a “library” (OBJECT library is fine). This makes it easier to write unit tests in a sub-directory without awkward cross-directory references.

The basic construct looks like this:

```cmake
set(myTarget foo) # for the "foo" executable
set(myDepend ${myTarget}Lib) # testable sources

add_library( ${myDepend} OBJECT ... )
add_executable( ${myTarget} ... )
target_link_libraries( ${myTarget} ${myDepend} ...)

```

To facilitate this pattern, I’ve created a macro in the top-level CMakeLists.txt:

```cmake
macro( DeclProg target )
  set( myTarget ${target} )
  set( myDepend ${myTarget}Lib )

  add_library( ${myDepend} OBJECT )
  add_executable( ${myTarget} )
  target_link_libraries( ${myTarget} PRIVATE {$myDepend} )
endmacro()

```

Then, in the “foo/CMakeLists.txt”, I just do

```cmake
DeclProg( foo )

target_sources( ${myDepend} PUBLIC foo1.cc )
target_sources( ${myTarget} PRIVATE main.cc )

# as needed
target_link_libraries( ${myDepend} PUBLIC
  #any libraries needed
)

```

Unfortunately, this is causing linker errors with multiple definitions of code. Running `make VERBOSE=1` I can see this link line (line breaks added for readability):

```bash
c++ -g "CMakeFiles/foo.dir/main.cpp.o"
 "CMakeFiles/foo.dir/foo1.cpp.o"
 "CMakeFiles/foo.dir/foo1.cpp.o"
 CMakeFiles/foo.dir/cmake_device_link.o
 -o foo
 -L/usr/local/cuda/targets/x86_64-linux/lib <elided various libraries>

```

Why is `foo1.cpp.o` being listed twice on the link line?

CMake: **3.26.1**  
RHEL 9  
gcc 12.2.1  
CUDA 12.1.0 (the cuda code is in static libraries, which triggers the `cmake_device_link.o` file)

---

<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: [June 7, 2023, 10:04pm UTC](https://discourse.cmake.org/t/macros-target-link-library-target-sources-evaluation-questions/8279/2 "2023-06-07T22:04:47Z")

</div>

> [@jwm](#):
>
> `target_sources( ${myDepend} PUBLIC foo1.cc )`

`PUBLIC` sources are added to the target itself _and anything that links to it_. Use `PRIVATE` instead.

---

<div class="post-metadata">

### Author: ![jwm](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jwm/32/654_2.png) [@jwm](https://discourse.cmake.org/u/jwm)
#### Post date: [June 7, 2023, 10:08pm UTC](https://discourse.cmake.org/t/macros-target-link-library-target-sources-evaluation-questions/8279/3 "2023-06-07T22:08:46Z")

</div>

Thanks @ben.boeckel . That was the ticket.
