0

I'm trying to setup a project that would consist of two executables: the actual application app and a test application test (i.e. executable that runs unit tests).

Obviously, test depends on functions/classes defined in app, meaning that correct build order has to be ensured. What is more however, app has a few external dependencies of its own, e.g. boost, which makes test transitively dependent on them as well.

What is the most idiomatic way of resolving these dependencies?

Two approaches I tried are:

  1. Make an intermediate app_lib library target, consisting of all source files except main.cpp, then link both executables against it (target_link_libraries(test PRIVATE app_lib)).
  2. Set ENABLE_EXPORTS property on app target, allowing test to link against it directly (target_link_libraries(test PRIVATE app)).

While both of these approaches work, they both seem quite hacky. The latter feels a tad better but if I understand it correctly, it was originally meant to enable plugin development, hence the "hacky" feeling.

To reiterate - what would be the correct way of setting up such project? Are these two the only possible solutions or there is another, better one?

mdx
  • 534
  • 3
  • 16
  • `test depends on app` Does `test` application _call_ `app`? `which makes test transitively` Why? If `test` does `system("./app");` why would `test` need `boost`? `Make an intermediate app_lib library target, consisting of all source files except main.cpp, then link both executables against it (target_link_libraries(test PRIVATE app_lib)).` Yes, do that. – KamilCuk May 29 '21 at 14:00
  • "why would `test` need `boost`" - For instance when one of the functions in `app` explicitly depends on `boost` and needs to be unit tested in `test`. – mdx May 29 '21 at 14:08
  • `of the functions in app` so `test` does not depend on the app, `test` depends on the function. Ergo, it's a library. – KamilCuk May 29 '21 at 14:10
  • Fair enough, edited the question for accuracy, but it's not vital for the issue imo. – mdx May 29 '21 at 14:18
  • Which test system do you use? The answer would depend from that. E.g. in case of GTest, see that question: https://stackoverflow.com/questions/23088252/how-to-test-an-exe-with-google-test. – Tsyvarev May 29 '21 at 14:33
  • @Tsyvarev I think you misunderstood me. I'm not trying to test the executable, I'm talking about unit testing particular classes and functions defined in its source code. – mdx May 29 '21 at 14:39
  • 1
    "I'm not trying to test the executable" and "I'm talking about unit testing particular classes and functions from its source code" - aren't they are the same purposes? At least, the [first answer](https://stackoverflow.com/a/23138390/3440745) to the question suggests to move definitions of the tested functions from the executable to intermediate library. – Tsyvarev May 29 '21 at 14:46
  • You could also reuse **sources** of your `app` application in the `test` application: by having `app` to be created with `add_executable(app main.cpp source1.cpp source2.cpp)`, you could create `test` application with `add_executable(test_app test.cpp source1.cpp source2.cpp)`. Instead of reusing source files, you could reuse **object** files: create objects with `add_library(common_objects OBJECT source1.cpp source2.cpp)`, and use them both for `app` - `target_link_libraries(app PRIVATE common_objects) - and for `test`: `target_link_libraries(test_app PRIVATE common_objects)`. – Tsyvarev May 29 '21 at 14:57
  • @Tsyvarev I dismissed the linked question too early, apologies. It really does speak about analogous issue. And, oh well, it seems that making it lib + exe is the de facto standard way of doing this. – mdx May 29 '21 at 14:57
  • Thanks for the suggestion with reusing object files as well, I'll check how it plays out. – mdx May 29 '21 at 15:00

0 Answers0