ossia / libossia

A modern C++, cross-environment distributed object model for creative coding and interaction scoring
https://ossia.io
GNU Lesser General Public License v3.0
204 stars 33 forks source link

Boost dependency sucks #462

Open avilleret opened 5 years ago

avilleret commented 5 years ago

well, most of the time it's fine

but when trying to build libossia with something else that also needs boost, then it could be a nightmare... if you want to crosscompile then you won't sleep for few nights...

For example when trying to build an openframeworks application (which needs boost_system and boost_filesystem) CMake finds boost but when compiling header are not found...

how could we solve that ? could we make our own boost namespace ? with only what we really need ?

avilleret commented 5 years ago

on another scenario, I can build boost library myself with something like :

add_custom_command( OUTPUT ${BOOST_SYSTEM_LIBRARY}
    COMMAND ./bootstrap.sh --with-libraries=system
    COMMAND ./b2 ${BOOST_B2_FLAGS}
    WORKING_DIRECTORY ${3RDPARTY_FOLDER}/libossia/3rdparty/boost_1_68_0
)
add_custom_target(boost_system DEPENDS ${BOOST_SYSTEM_LIBRARY})

but in the openframeworks case, it's harder because openframeworks lib is build separately. So I need to build it against libossia boost version to make it work properly...

avilleret commented 5 years ago

hum, I found a bug in FindBoost behavior When we do find_package(Boost 1.${BOOST_MINOR} QUIET) in https://github.com/OSSIA/libossia/blob/master/CMake/OssiaDeps.cmake#L93

and if there is a boost somewhere which doesn't fit the version requirement then Boost_INCLUDE_DIR is set to this version and after downloading boost source and searching again with https://github.com/OSSIA/libossia/blob/master/CMake/OssiaDeps.cmake#L123 Boost_INCLUDE_DIR still point to the non valid one.

resetting Boost_INCLUDE_DIR if version doesn't match fixes the issue

so now I can build software that include two different boost version I'm scared...

jcelerier commented 5 years ago

hmmm... just did a quick check (grep -R '<boost/' | awk '{ print $2 }' | sort | uniq) and here's the used headers :

<boost/algorithm/string/case_conv.hpp>
<boost/algorithm/string/classification.hpp>
<boost/algorithm/string/erase.hpp>
<boost/algorithm/string.hpp>
<boost/algorithm/string/predicate.hpp>
<boost/algorithm/string/replace.hpp>
<boost/algorithm/string/split.hpp>
<boost/any.hpp>
<boost/bind.hpp>
<boost/circular_buffer.hpp>
<boost/concept/assert.hpp>
<boost/config.hpp>
<boost/container/small_vector.hpp>
<boost/container/static_vector.hpp>
<boost/fusion/adapted.hpp>
<boost/fusion/adapted/std_pair.hpp>
<boost/graph/adjacency_list.hpp>
<boost/graph/breadth_first_search.hpp>
<boost/graph/connected_components.hpp>
<boost/graph/graph_concepts.hpp>
<boost/graph/graphviz.hpp>
<boost/graph/labeled_graph.hpp>
<boost/graph/named_function_params.hpp>
<boost/graph/strong_components.hpp>
<boost/graph/topological_sort.hpp>
<boost/graph/transitive_closure.hpp>
<boost/lexical_cast.hpp>
<boost/optional.hpp>
<boost/predef.h>
<boost/range/algorithm/lexicographical_compare.hpp>
<boost/spirit/home/x3.hpp>
<boost/spirit/include/qi_symbols.hpp>
<boost/type_traits/function_traits.hpp>

All the "graph" stuff is only used in the dataflow part and thus not when making the openframeworks / max / pd / etc... builds. Likewise for circular_buffer.

This leaves

<boost/algorithm/string/case_conv.hpp>
<boost/algorithm/string/classification.hpp>
<boost/algorithm/string/erase.hpp>
<boost/algorithm/string.hpp>
<boost/algorithm/string/predicate.hpp>
<boost/algorithm/string/replace.hpp>
<boost/algorithm/string/split.hpp>
<boost/any.hpp>
<boost/bind.hpp>
<boost/concept/assert.hpp>
<boost/config.hpp>
<boost/container/small_vector.hpp>
<boost/container/static_vector.hpp>
<boost/fusion/adapted.hpp>
<boost/fusion/adapted/std_pair.hpp>
<boost/lexical_cast.hpp>
<boost/optional.hpp>
<boost/predef.h>
<boost/range/algorithm/lexicographical_compare.hpp>
<boost/spirit/home/x3.hpp>
<boost/spirit/include/qi_symbols.hpp>
<boost/type_traits/function_traits.hpp>

any and optional are in C++17 so we could force their use, however in macOS they tie the C++ standard library to the OS version and as such using the standard ones would restrict to macOS 10.14 and later. But this would give :

<boost/algorithm/string/case_conv.hpp>
<boost/algorithm/string/classification.hpp>
<boost/algorithm/string/erase.hpp>
<boost/algorithm/string.hpp>
<boost/algorithm/string/predicate.hpp>
<boost/algorithm/string/replace.hpp>
<boost/algorithm/string/split.hpp>
<boost/bind.hpp>
<boost/concept/assert.hpp>
<boost/config.hpp>
<boost/container/small_vector.hpp>
<boost/container/static_vector.hpp>
<boost/fusion/adapted.hpp>
<boost/fusion/adapted/std_pair.hpp>
<boost/lexical_cast.hpp>
<boost/predef.h>
<boost/range/algorithm/lexicographical_compare.hpp>
<boost/spirit/home/x3.hpp>
<boost/spirit/include/qi_symbols.hpp>
<boost/type_traits/function_traits.hpp>

The string algorithms one are "easy" to get rid of because they're mostly simple algorithms that could be rewritten (just as well ?); they are used from the following files:

ossia-max/src/parameter_base.cpp:#include <boost/algorithm/string/case_conv.hpp>
ossia-max/src/parameter_base.cpp:#include <boost/algorithm/string.hpp>
ossia-max/src/node_base.cpp:#include <boost/algorithm/string/case_conv.hpp>
ossia-max/src/utils.cpp:#include <boost/algorithm/string/predicate.hpp>
ossia-max/src/client.cpp:#include <boost/algorithm/string.hpp>
ossia-max/src/device.cpp:#include <boost/algorithm/string/case_conv.hpp>
ossia-pd/src/node_base.cpp:#include <boost/algorithm/string/case_conv.hpp>
ossia-pd/src/parameter.cpp:#include <boost/algorithm/string/case_conv.hpp>
ossia-pd/src/client.cpp:#include <boost/algorithm/string.hpp>
ossia-pd/src/utils.cpp:#include <boost/algorithm/string/predicate.hpp>
ossia-qt/device/qml_model_property.cpp:#include <boost/algorithm/string.hpp>
ossia/network/base/node_functions.cpp:#include <boost/algorithm/string/case_conv.hpp>
ossia/network/base/node_functions.cpp:#include <boost/algorithm/string/predicate.hpp>
ossia/network/base/name_validation.cpp:#include <boost/algorithm/string/classification.hpp>
ossia/network/base/name_validation.cpp:#include <boost/algorithm/string/split.hpp>
ossia/network/base/node.cpp:#include <boost/algorithm/string/predicate.hpp>
ossia/network/common/path.cpp:#include <boost/algorithm/string/classification.hpp>
ossia/network/common/path.cpp:#include <boost/algorithm/string/predicate.hpp>
ossia/network/common/path.cpp:#include <boost/algorithm/string/replace.hpp>
ossia/network/common/complex_type.cpp:#include <boost/algorithm/string.hpp>
ossia/network/dataspace/detail/list_units.hpp:#include <boost/algorithm/string/case_conv.hpp>
ossia/network/generic/generic_node.cpp:#include <boost/algorithm/string/replace.hpp>
ossia/network/osc/osc.cpp:#include <boost/algorithm/string.hpp>
ossia/network/oscquery/detail/query_parser.cpp:#include <boost/algorithm/string.hpp>
ossia/network/oscquery/oscquery_mirror.cpp:#include <boost/algorithm/string.hpp>
ossia/network/oscquery/oscquery_mirror.cpp:#include <boost/algorithm/string/erase.hpp>
ossia/network/value/format_value.hpp:#include <boost/algorithm/string/replace.hpp>
ossia/network/value/value.cpp:#include <boost/algorithm/string/replace.hpp>
ossia/preset/preset.cpp:#include <boost/algorithm/string.hpp>

and here are the actual uses (I think that some headers are useless, gonna check that asap) :

ossia-max/src/parameter_base.cpp:      boost::algorithm::to_lower(access_mode);
ossia-max/src/parameter_base.cpp:      boost::algorithm::to_lower(bounding_mode);
ossia-max/src/parameter_base.cpp:      if(boost::algorithm::ends_with(addr, target)) {
ossia-max/src/client.cpp:    boost::algorithm::to_lower(protocol_name);
ossia-pd/src/parameter.cpp:    boost::algorithm::to_lower(type);
ossia-pd/src/client.cpp:    boost::algorithm::to_lower(protocol_name);
ossia/network/base/node_functions.cpp:  while (boost::algorithm::starts_with(address, "/"))
ossia/network/base/node_functions.cpp:  while (boost::algorithm::ends_with(address, "/"))
ossia/network/base/node_functions.cpp:    boost::algorithm::to_lower(s1);
ossia/network/base/node_functions.cpp:    boost::algorithm::to_lower(s2);
ossia/network/common/complex_type.cpp:  boost::algorithm::to_lower(str);
ossia/network/common/complex_type.cpp:  boost::algorithm::to_lower(str);
ossia/network/dataspace/detail/list_units.hpp:      boost::algorithm::to_lower(dataspace_name);
ossia/network/dataspace/detail/list_units.hpp:          std::string s = boost::algorithm::to_lower_copy(std::string(un));
ossia/network/oscquery/oscquery_mirror.cpp:  uri = boost::algorithm::ierase_first_copy(uri, "http://");
ossia/network/oscquery/oscquery_mirror.cpp:  uri = boost::algorithm::ierase_first_copy(uri, "https://");
ossia/network/oscquery/oscquery_mirror.cpp:  uri = boost::algorithm::ierase_first_copy(uri, "ws://");
ossia/network/oscquery/oscquery_mirror.cpp:  uri = boost::algorithm::ierase_first_copy(uri, "wss://");
ossia/network/value/format_value.hpp:    boost::algorithm::replace_all(str, "\"", "\\\"");

This leaves

<boost/bind.hpp>
<boost/concept/assert.hpp>
<boost/config.hpp>
<boost/container/small_vector.hpp>
<boost/container/static_vector.hpp>
<boost/fusion/adapted.hpp>
<boost/fusion/adapted/std_pair.hpp>
<boost/lexical_cast.hpp>
<boost/predef.h>
<boost/range/algorithm/lexicographical_compare.hpp>
<boost/spirit/home/x3.hpp>
<boost/spirit/include/qi_symbols.hpp>
<boost/type_traits/function_traits.hpp>
jcelerier commented 5 years ago

there could be a possibility: putting boost in a different namespace. bcp allows this :

https://www.boost.org/doc/libs/1_69_0/tools/bcp/doc/html/index.html
avilleret commented 5 years ago

there could be a possibility: putting boost in a different namespace. bcp allows this

that was my first feeling