Skip to content
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

QNX Compatibility #1968

Draft
wants to merge 13 commits into
base: develop
Choose a base branch
from
Draft

QNX Compatibility #1968

wants to merge 13 commits into from

Conversation

JaiXJM-BB
Copy link

Compatibility for the QNX Operating System, versions 7.1 and 8.0. As discussed in #1914 .

Changes in Detail:
Each change will have a GitHub comment attached explaining why it is necessary. Below is an overview of the changes as a whole.
All changes are wrapped in appropriate if(QNX) or if defined(__QNX__) statements.

  • About half of the CMake changes were to adjust compiling options for all builds to accommodate QNX. These generally already existed for other OSes, and simply needed a check for QNX tacked on as well.

  • Some install commands were changed to respect CMAKE_INSTALL_INCLUDEDIR if QNX is being compiled for, instead of using include/.

  • The rest of the CMake changes enable the compilation of tests. This is so that tests can be run on QNX target, as cross-compilation is required and thus using CTest is unideal.
    -- There are two environment variables added to support this, both of which only apply if the target is a QNX system. These are $QNX_TARGET_DATASET_DIR and $QNX_BUILD_TESTS. $QNX_TARGET_DATASET_DIR is set to wherever the examples/Data directory will be cloned to on the target when compiling tests to avoid some file location errors. Tests only build if $QNX_BUILD_TESTS is set. (I have these as environment variables as it was slightly cleaner when I was building, but can easily be changed to CMake options if needed)

  • There are two non-CMake changes here.
    -- One adds to a gcc bugfix that is slightly worse on qcc (QNX Compiler)
    -- The second switches a placeholder in config.h.in to a different filepaths on QNX.

* GitLab version (branch QNX_7.1_v4.1.1)

* ADDED: Build tested with target `install` or `all` if cross compiling for QNX

* ADDED: Test Installation when building with QNX (Review this for upstreaming)

* UPDATED: Build tests, fixed some unit tests. Floating points still off.

* UPDATED: Tests Fix

* UPDATED: all non-serialization tests working.

* QNX 8.0: Working version.

* REMOVED: Removal of test prints

* UPDATED: formatting to match, removed commented out testing lines
set_target_properties(${script_name} PROPERTIES EXCLUDE_FROM_ALL ON)
if(NOT QNX OR NOT DEFINED ENV{QNX_BUILD_TESTS})
set_target_properties(${script_name} PROPERTIES EXCLUDE_FROM_ALL ON)
endif()
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allows tests to be built when compiling for QNX with option QNX_BUILD_TESTS

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there something specific to QNX that you need to use an environment variable? We normally do "make check" to run the tests.


if(NOT QNX OR NOT DEFINED ENV{QNX_BUILD_TESTS})
set_target_properties(${target_name} PROPERTIES EXCLUDE_FROM_ALL ON)
endif()
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allows tests to be built when compiling for QNX with option QNX_BUILD_TESTS

#Install in the install include directory rather than at the install prefix.
install(FILES ${ceres_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gtsam/3rdparty/ceres)
endif()
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a number of changes identical to this one, which handle the correct include directory for installation in qnx. Note that CMAKE_INSTALL_INCLUDEDIR should point to include/ by default, so in the future the QNX line could just replace the default one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is CMAKE_INSTALL_INCLUDEDIR now by default? If incorrect, should we do a PR on that first?

#For config.in searches
if(QNX)
set(QNX_TARGET_DATASET_DIR "$ENV{QNX_TARGET_DATASET_DIR}")
endif()
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dataset directory is not examples/Data when running tests out of the source tree, so this is required to properly set the path.

file(GLOB base_headers_tree "treeTraversal/*.h")
install(FILES ${base_headers_tree} DESTINATION include/gtsam/base/treeTraversal)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slightly rearranged for convenience, but same as the other include directory changes.

// QCC (The QNX GCC-based Compiler) also has this issue, but it also extends to trivial destructor.
#if defined(__QNX__)
namespace std { template<> struct is_trivially_destructible<boost::serialization::U> : std::false_type {}; }
#endif
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84075 issue extendes to QNX, but also affects is_trivially_destructible. Luckily it can be fixed in the same way.

#else
//Set toolbox path to the path on the target.
#define GTSAM_INSTALLED_DATASET_DIR "@QNX_TARGET_DATASET_DIR@/gtsam_examples/Data"
#endif

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Data path changed when testing outside of the source tree on QNX.

@@ -1,7 +1,12 @@
# Install headers
set(subdir discrete)
file(GLOB discrete_headers "*.h")
install(FILES ${discrete_headers} DESTINATION include/gtsam/discrete)
# FIXME: exclude headers
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This FIXME was not added by me; so I assume it may have been changed in the 430 or so commits I needed to merge into this one to get up to develop. This should be double checked before merging.

@@ -303,7 +303,7 @@ TEST(Ordering, MetisLoop) {
symbolicGraph.push_factor(0, 5);

// METIS
#if defined(__APPLE__)
#if defined(__APPLE__) || defined(__QNX__)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follows apple ordering in test output.

deserializeFromXMLFile(GTSAM_SOURCE_TREE_DATASET_DIR
"/../../gtsam/nonlinear/tests/priorFactor.xml",
factor_deserialized_xml);
#else
bool c = deserializeFromXMLFile(
"priorFactor.xml",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, a filepath search error on QNX. Changed to look in the same directory now, as outside of source tree.

@@ -687,7 +687,7 @@ TEST(SymbolicBayesTree, COLAMDvsMETIS) {
{
Ordering ordering = Ordering::Create(Ordering::METIS, sfg);
// Linux and Mac split differently when using Metis
#if defined(__APPLE__)
#if defined(__APPLE__) || defined(__QNX__)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, ordering results on QNX seem to follow the APPLE results from Metis.

string path(TOPSRCDIR "/gtsam_unstable/discrete/examples/");
#else
string path(""); //Same Directory
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another path change when testing out of the source tree.

std::vector<size_t> keys{0, 1, 2, 3, 4};
#else
//Anything where 2 is before 0 will work.
std::vector<size_t> keys{2, 0, 3, 1, 4};
Copy link
Author

@JaiXJM-BB JaiXJM-BB Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error was quite interesting; but the summary is that 0 1 2 3 4 will partition into 3-4, 0-1-2 instead of 0-1, 2-3-4 on QNX. This is an equally valid partition, it is just interesting that the tiebreaker seems to be related to ordering here.

Copy link
Member

@dellaert dellaert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two big comments, questions:

  • Since there are so many changes related to CMAKE_INSTALL_INCLUDEDIR, could we not fix that first in a PR first, if it is fixable?
  • Can you explain a bit more as to why QNX needs special handling of tests, and how?

set_target_properties(${script_name} PROPERTIES EXCLUDE_FROM_ALL ON)
if(NOT QNX OR NOT DEFINED ENV{QNX_BUILD_TESTS})
set_target_properties(${script_name} PROPERTIES EXCLUDE_FROM_ALL ON)
endif()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there something specific to QNX that you need to use an environment variable? We normally do "make check" to run the tests.

#Install in the install include directory rather than at the install prefix.
install(FILES ${ceres_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gtsam/3rdparty/ceres)
endif()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is CMAKE_INSTALL_INCLUDEDIR now by default? If incorrect, should we do a PR on that first?

#Install in the install include directory rather than at the install prefix.
install(FILES ${ceres_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gtsam/3rdparty/ceres)
endif()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add newline at end

else()
#Install in the install include directory rather than at the install prefix.
install(FILES metis.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gtsam/3rdparty/metis)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment. And, add newline at end :-)

@dellaert
Copy link
Member

Re-reading your PR comment: indeed, I'd rather not bring in environment variables as a way to configure, as I don't think we use them in any other case - except maybe if third party libraries look for them.

@JaiXJM-BB
Copy link
Author

Re-reading your PR comment: indeed, I'd rather not bring in environment variables as a way to configure, as I don't think we use them in any other case - except maybe if third party libraries look for them.

Sounds good; there is nothing that requires an environment variable on QNX's end - these could easily be a CMake Flag or removed entirely.

With regards to make check, this doesn't work for QNX (or at least in my experience I've never seen it done or gotten it to work) since ctest runs the files on whatever machine is compiling, and there isn't a CMake port on QNX or a make utility available either, hence cross-compilation. This is why tests are being compiled into executables, so that users can copy them over and run them manually. It does add a lot of compile time which is why I had them on a toggle.

That being said - We could keep unit test cmake changes on the QNX fork or in a patchfile in the QNX documentation repo - that way environment variables/extra cmake options don't affect your develop branch and any user that does want unit test control can find it elsewhere.

@JaiXJM-BB
Copy link
Author

For CMAKE_INSTALL_INCLUDEDIR, my understanding is that it defaults to include per https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html#module:GNUInstallDirs

Making a separate PR first to fix these is a good idea- there's also CMAKE_INSTALL_LIBDIR, CMAKE_INSTALL_BINDIR, and more that apply as well. Not sure if those are already in use.

@dellaert
Copy link
Member

Gotcha. Take a look at the windows testing: there we created one executable per “folder”, which cut down on compile time quite a bit.

@dellaert
Copy link
Member

It seems the default is indeed include, so it seems that the code in your else clause is the correct way, right? In that case, maybe we don't need a new PR, just use remove the if-then-else and we'll merge this new correct way instead. @jlblancoc am I missing something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants