-
-
Notifications
You must be signed in to change notification settings - Fork 649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tests inside a static library #21
Comments
well this is weird and unfortunate - will have to investigate this |
(Wild guess) If you're using Visual Studio, you may want to look at this note in the Google Test wiki (Mentioned here in the CATCH Google group). |
@martinmoene : Thanks for the suggestion :-) |
After testing, I can reproduce the problem with AppleClang, gcc 4.8 (ubuntu 64 bits), and MSVC 2013. However, I think I found a good potential solution! See pthom/DocTest_LibTest@e637352 If you add a dummy function in the static library and call it from the doctest main() function, then the tests will be run. What do you think? |
seems like what the google.test docs say - will add it to my docs too - thanks! |
Hi Viktor, Each file containing tests needs to be "registered" separately, so that you have to create a dummy function in each file that contains tests, and call it from the main() function. Based on my observations, the problem is not limited to Visual Studio (not anymore ?) : I can consistently reproduce it with AppleClang and gcc also... A more generic way to test a static library could be to add a DocTestRegister() function to the library : this function would call all the dummy functions, and it would be called by doctest's main() function. May be you will have a better idea (I hope so), because my solution is a bit tedious :-) |
Hi Viktor, Actually I fought to find a solution to this problem, and I made some helper cmake scripts for this. Would you mind giving me your opinion about them ? See https://github.com/pthom/doctest_registerlibrary |
I'll take a look - I do want to have a fix for this - this is the current thing I'm thinking about - thanks for the effort! |
omg! I did some research and there really is no way to fix this in a pretty way - the executable has to reference something from each object file from the static lib... (or if all object files from the static library reference each other like a linked list - then the executable needs to reference only 1 object file from the static library). Anyway I'll try to solve this only in cmake and without the need to modify any of the source files - with compile definitions (by iterating through the source files of the static library and also based on their count - will give some identifier to the executable (like I'll write here when it's done - in a few days. If I fail - then your solution would be the best. |
Hum, it seems I had an idea that was close to the python script you are mentioning, since I wrote some cmake functions that call a python script in order to generate the code that makes self registering work. Look at the repo I sent you, it might help you; and if you like the idea just let me know, I'd like to be able to help. If you do not like it, no worries though :-) |
Your approach is interesting ! Good luck with the preprocessor though, it is a difficult beast :-) your library proves that you are better at it than me |
Hi, |
:D I'm still delaying the finish of the 1.1 release. Actually my approach wouldn't work. I came up with a different one - if it doesn't work as well I will link in my FAQ to your project. I hope that I release 1.1 in the next 1-2 weeks with this fixed (or linked to your solution)... |
Thanks for the update. Keep me posted :D |
…t" located in "doctest_force_link_static_lib_in_target.cmake" users of CMake can force the linking of every object file from a static library to an executable/shared target. Not intrusive - using generated dummy headers in the build folder of the target, CMake target properties and compiler flags for including the headers to the appropriate sources. fixes #21
Sooo I think I solved the issue! Here is the commit message: Using a CMake function called "doctest_force_link_static_lib_in_target" like this located in examples/exe_with_static_libs/doctest_force_link_static_lib_in_target.cmake users of CMake can force the linking of every object file from a static library to an executable/shared target. Not intrusive - using generated dummy headers in the build folder of the target, CMake target properties and compiler flags for including the headers to the appropriate sources. Also it is fool proof - using "doctest_force_link_static_lib_in_target" on the same target/library pair won't cause trouble. even the scenario of linking in 2 shared objects with the same static lib with tests will work - no dummy function clashes when using the 2 shared objects together. what do you think? It's just a single .cmake file and it doesn't modify the source files or require python or a separate build step. still in the dev branch tough... EDIT: linux builds seem to fail - will investigate. EDIT 2: fixed the builds - the problem was that old cmake versions didn't support some target properties. the script now requires atleast cmake 3.0 |
Hello, |
Wow, you did some serious cmake trickery :-) I tested it and it worked with the following combinations :
I also works when you add tests to a file that was not using them, without re-running cmake.
I think it's just great ! May I suggest one additional thing : I am a lazy guy, and I like "ready to use" solutions. What do you think ? |
I have a few thoughts on this:
|
I agree. It might be enough to provide these functions as a code comment inside examples/exe_with_static_libs/readme.md People who might need would then copy / paste / adapt to their needs |
so I added the doctest_make_exe_for_static_lib function. It generates the main.cpp for the executable in the build folder. Does this suit your needs? |
I saw this, and I see no better solution since when a function comes from an included cmake, there is no way for this function to know in which folder it is implemented. Thanks for the great job! |
Hum... I'm afraid I found an issue with your solution. It's very easy to test : just create a dummy project with precompiled headers, change one of the file to "force include" a file with voluntary syntax errors => it will compile just fine. I tested this on Visual Studio 2010 and 2013. Though, it does work with libraries that do not use precompiled headers. |
I found this issue on the web but it isn't very clear. I did find one configuration that works though: // main.cpp
int main() { void f(); f(); } // a.cpp
void f() { printf("%d", from_force_included); } // b.cpp // c.cpp // pch.h
#include <stdio.h> // force_included.h
int from_force_included = 8; # CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(FI_TESTS)
include(../doctest/examples/exe_with_static_libs/doctest_force_link_static_lib_in_target.cmake)
include(../game/libs/third_party/ucm/cotire/CMake/cotire.cmake)
add_executable(FI_TESTS main.cpp a.cpp b.cpp c.cpp)
set_target_properties(FI_TESTS PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE)
set_target_properties(FI_TESTS PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "pch.h")
cotire(FI_TESTS) # used for precompiled headers
doctest_include_file_in_sources(force_included.h a.cpp) The above example works only in this configuration. cotire is used for pch stuff. If I change the order of the If I move the stuff from Here are the compiler flags for and for So in your case every source file from the static lib has a header force included into it without exception - including the source file that is 'compiling' the precompiled header - and that must be the result of the problems. That's unfortunate... I'm all out of tricks. Thanks for the huge donation! Hope you don't feel let down. |
|
Hi, Long time, no talk :-) Could you look at this and tell me your opinion : |
Thanks for discovering this! I'll write about it in the FAQ section about tests in static libraries and will also update my example! Btw version 1.2 should be released in the next 24 hours :) |
… is defined in cmake - now using an object library instead of a static library - thanks to github.com/pthom - relates #21
… is defined in cmake - now using an object library instead of a static library - thanks to github.com/pthom - relates #21
Hey, I'm currently using the following CMake module that disables the tests for a release version and exports all symbols for debug. Adding all symbols to the dynamic symbol table solves the issue and seems far more elegant. The option can be turned off for any subdirectory or target with
|
I'm a bit late to the show, but I noticed that the example here only works if the static library source files and main.cpp are in the same directory. If they reside in different directories I get unresolved symbols. Note: I moved lib1 source files to a new directory and added it with add_subdirectory from the root CMakeLists.txt Is there a workaround for this? |
Hi,
(This is more a question than an issue)
What is the recommended way to add tests inside a static library project ?
If I compile a library (which includes TEST_CASE(s)) as a static library,
and then I try to run the tests from this library by creating a target that links
to it, the test suite is actually empty (i.e I guess the tests were stripped at link time)
Am I doing something wrong, or is there a way to circumvent this?
Below is an example of what I am trying to achieve (using cmake):
MyLibrary/CMakeLists.txt :
MyMainProgram/CMakeLists.txt :
A working example can be found at https://github.com/pthom/DocTest_LibTest
The text was updated successfully, but these errors were encountered: