-
Notifications
You must be signed in to change notification settings - Fork 120
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
CMake build script updates #140
Conversation
Codecov Report
@@ Coverage Diff @@
## master #140 +/- ##
==========================================
- Coverage 37.53% 37.52% -0.02%
==========================================
Files 52 52
Lines 2251 2268 +17
==========================================
+ Hits 845 851 +6
- Misses 1406 1417 +11
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for doing this. Some comments and questions, mostly about my ignorance of CMake, conan and general editor configuration.
@@ -0,0 +1,82 @@ | |||
from conans import CMake, ConanFile, tools |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to have this here, but forgive my ignorance: how might this work to get seasocks in conan build center?
Also it looks like we're missing a test_package -- have you been able to test that this seasocks build works?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't help at all for getting seasocks in cci, because it doesn't follow cci practices.
Also, in my own experience, using a conanfile makes it easier to test on ci.
If you ever lose your mind and want to add support for Windows, then you can use it to build on appveyor.
A simple conan install.. && conan build .. & conan test ..
should work™ .
In theory, now you can add a job on travis that uses this conanfile.
The test()
method can be used to run the unit tests.
I haven't added a test_package
, because the intention of this recipe is not to package seasocks
, but to allow it to build (and test).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I can't see that we'd ever use conan to build seasocks in this case (it has so few upstream dependencies). My projects that do have upstream deps do use conan, but I don't want to rely on it here. However, that doesn't mean this isn't super useful!
We will definitely add a conan test job once this is working, how would you suggest doing so with your changes here?
conan install.. && conan build .. & conan test ..
Aside: I do so hate the multi-stage aspect of conan. In all my experience, if there are manual steps, then people will forget them! In my own projects I always use the conan.cmake file to make conan part of the build itself...I've spent too long debugging things like "oh, you forgot to conan install:? You're probably building against the old libraries...argh!")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This requires adding new jobs, that will run the conan commands.
I would add a CONAN_INSTALL_ARGS environment variable to .travis.yml.
Aside: I do so hate the multi-stage aspect of conan. In all my experience, if there are manual steps, then people will forget them! In my own projects I always use the conan.cmake file to make conan part of the build itself...I've spent too long debugging things like "oh, you forgot to conan install:? You're probably building against the old libraries...argh!")
It's a matter of taste I guess.
I always try to make my project package manager agnostic.
This allows me to build with the libraries of a linux package manager.
(Matt accidentally edited this comment; I hope I've un-edited back appropriate)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops! I meant to reply!!! Not edit your comment 😊
I tried to say:
This requires adding new jobs, that will run the conan commands.
I would add a CONAN_INSTALL_ARGS environment variable to .travis.yml.
I get that, just quickly, how might one actually build seasocks using conan? conan install .. && conan build .. && conan test .. like you mentioned above? Would that actually run the tests? Thanks again for teaching me this.
I always try to make my project package manager agnostic.
Got it: that makes sense. In my world having the one way that just works and is reproducible is most important, but I have the luxury of mostly getting to choose this within my team etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get that, just quickly, how might one actually build seasocks using conan? conan install .. && conan build .. && conan test .. like you mentioned above? Would that actually run the tests? Thanks again for teaching me this.
I was wrong there. The intended use of conan test
is only to test conan packages.
What can be done is use the virtualenv generator. The tests can then be run from any script (bash/python/ctest/...). The virtualenv makes sure that paths of all dependencies are in the search path (LD_LIBRARY_PATH/PATH/DYLD_LIBRARY_PATH/...). This is especially required for shared library dependencies.
I always try to make my project package manager agnostic.
Got it: that makes sense. In my world having the one way that just works and is reproducible is most important, but I have the luxury of mostly getting to choose this within my team etc
Check the conanfile.py
of thie recipe. It writes a wrapper CMakeLists.txt
in the build directory that includes the source directory. It is more or less the inverse approach as your conan.cmake
. (conan.cmake's driver is cmake. In this pr, the driver is conan)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try and work through that once we're merged in. I'm not quite following but I imagine trying to do it will elucidate more than reading dry documentation.
src/CMakeLists.txt
Outdated
if(SEASOCKS_SHARED) | ||
add_subdirectory(main/web) | ||
|
||
if (SEASOCKS_EXAMPLE_APP) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the example app only built against the shared library? It should work against the lib too? (unless I'm missing something)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cmake script currently builds both shared and static libraries, which can be disabled.
Because the examples+tests link to the shared library, this dependency might be missing
I'll take another look at this and add a new option: SEASOCKS_APPS_USE_SHARED
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to make things more complex: I was just trying to understand :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still, this is a consequence of not using cmake's BUILD_SHARED_LIBS
.
Because right now, the static library is built, but not used/tested anywhere.
This is a potential bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @madebr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What option do you prefer?
- Add a
SEASOCKS_APPS_USE_SHARED
that lets the user choose to what type of library the examples/tests link. This has the potential for people forgetting to test linking to the static library. - Add the examples/tests twice.
The examples/tests can be built once, but linked twice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not worried either way: I doubt there are many categories of errors which mean that static libs work when dynamic don't. That said; if it's not much work then I'd prefer the second option, but the first works too if the CI system matrix is expanded to build with it on and off.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've applied the second approach done this in the latest commit.
Most of the additional complexity comes from us building both shared and static libraries (as opposed to using cmake's BUILD_SHARED_LIBS
).
When configuring cmake as cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE=ON
, the number of source compilatations should be equal, but the number of linkings should be doubled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Thanks @madebr :) Sorry about the codecov thing. I wish I knew how to stop it being quite so opinionated... |
project(Seasocks VERSION 1.4.3) | ||
|
||
if(WIN32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe Mac OS should be included too? Test for not-linux?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, test should include APPLE
endif () | ||
|
||
find_package(Threads) | ||
find_package(PythonInterp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, didn't know that package! 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's superseded by FindPython3
, but that's not available on older cmake releases.
target_link_libraries(seasocks_so PRIVATE ${CMAKE_THREAD_LIBS_INIT} "${ZLIB_LIBRARIES}") | ||
endif() | ||
set_target_properties(seasocks_so PROPERTIES OUTPUT_NAME seasocks VERSION ${PROJECT_VERSION}) | ||
if (SEASOCKS_SHARED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the main difference between the static / shared part is target name, they can be extracted into a macro I guess. This would reduce the code duplication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
I didn't because I wasn't sure you would agree with the complexity I was adding.
Doohh … few minutes to slow 🤦 |
Thanks both! I'm just discussing in Slack how best to get an official release done. Like @madebr says it will be the basis... |
haha nps @offa we can fix these little minor issues in the main branch! |
conan-io/conan#4734 was just linked in the Slack and conan-io/conan-center-index#22 too |
So; let's get any late-breaking changes in and then plan to cut a release later? Then I'll try and baby sit the process of getting it into cci |
I'm not through the complete discussion, so sorry for the stupid question: But why is it necessary to include literally every target twice (static / shared)? Especially the tests don't make sense to me right now (… again, sorry this not-really-prepared question). |
conan-io/conan-center-index#22 (comment) sums it up, I think
|
The idea is to ensure CI builds et all build and link with both the static and shared library if configured. We can definitely consider changing this: it's possible we can adopt a more "build one or the other" approach too. I was scared to break backwards compatibility with people needing both, but maybe it's costing too much to support both simultaneously. @madebr mentioned a CMAKE setting to pick one or the other. |
👍 Sounds good to me! Thanks all! |
See #140 (comment) for our discussion |
Yeah, this would make sense. The current situation is a little … untypical … 😄. |
Ok cool! Unless someone has a burning urge I'll try and work out how to move to |
@mattgodbolt |
If |
It's not problematic at all. I wouldn't add a new option and just keep the default one to fit in with the rest. |
Maybe I'm missing something here? Wouldn't having |
@mattgodbolt So only one library will be built, but the type depends on the option. Adding both options, would make it possible to build the shared library twice. |
Understood. So why would we have |
Perhaps I misunderstand:
"the default one" => BUILD_SHARED_LIBS |
You could do that, but then you would duplicate cmake's behavior.
and use it as:
|
Perfect! I get it now! Thanks yet again :) |
I think you can remove the |
I disagree here: the original use case of seasocks was embedding it (statically) in a shared library... fPIC being independent of "build a shared object" is really important :) |
(plus folks building executables with |
You can use Alternatively, you can also provide a |
Oh lovely! There's a CMakeful solution for everything: thanks! |
I'm tying myself in knots rather here. Will put a PR together which will hopefully be 90% there and then I'd love your help getting it over the finish line. |
No problem, the changes shouldn't be that big. |
So far one weird cmake thing and one conan thing. Might have to PR with them in and ask for your help. Will spend another 10m on it first :) |
Hello!
As promised after our chat at cpplang.slack#conan, a pr for better conan support.
I've not (yet) looked at Windows support.
What did I change?
(too bad btw that
SEASOCKS_SHARED
andSEASOCKS_STATIC
option to build shared and static libraries together.I left the possibility for building a static library without PIC support: see
seasocks_obj
vsseasock_pic_obj
target.@ONLY
toconfigure
to don't replace cmake type variables. This does not change anything, but is safer for the future.CMAKE_MODULE_PATH
so some module paths can be overridden by external scripts.SeasocksTargets.cmake
and generate aSeasockConfig.cmake
.Also make sure to link to
ZLIB::ZLIB
andThreads::Threads
to avoid paths of the build machine being present in the exported cmake scripts. Note that this requires afind_package(Threads REQUIRED)
andfind_package(ZLIB REQUIRED)
in the generatedSeasocksConfig.cmake
.add_subdirectory
. No functional change. But nicer imho.Adding a
conanfile.py
to your repo allows the master branch in-tree, without doing releases.e.g.:
cmake --open
.Also, I made sure to not patch the sources or include
conanbuildinfo.cmake
in your cmake scripts.Cheers