robotics-at-maryland / tortuga

Robotics @ Maryland Autonomous Underwater Vehicle
14 stars 31 forks source link

What must be done to remove scripts/setenv? #5

Open jwonders opened 11 years ago

jwonders commented 11 years ago

See this issue for the discussion that led to wanting to figure out what all will need to be done to remove scripts/setenv.

jlisee commented 11 years ago

If you want to remove it you have to address it's main use cases:

  1. Setting up the environment so you can use software installed in RAM_ROOT_DIR
  2. Defining environment variables allowing are locally built binaries to be run
  3. Defining the root of the tree (RAM_SVN_DIR) so files can be located at runtime

Use case by use case solutions:

  1. Not sure there is one, the popular python virtualenv system works very similarly to setenv
  2. You can use rpath so that you don't need LD_LIBRARY_PATH
  3. You can attempt to use relative paths

Now back to original issue, how do you use IDEs? Just set the paths that scripts/setenv sets manually in the IDE. This is how I used pydev to do much of the original R@M python development. With something like Eclipse you would probably be able to automate this as well.

jsternberg commented 11 years ago

Right now with CMake, it's already set up in a way where RAM_ROOT_DIR isn't used. scripts/setenv isn't needed for compilation at the current moment. It's only needed at runtime. There's a special job defined to run first in the build to test for scripts/setenv, which was only put there because the automatic running of tests needed it and everyone kept getting confused by the error messages when you forgot to run the script, so I removed the ability to compile without setting scripts/setenv.

RAM_SVN_DIR is the important one (and the reason scripts/setenv needs to be run for unit tests), as certain code relies on its existence. Here's a quick grep looking for where it's used in the code.

core/src/PythonConfigNodeImp.cpp:413:               << "    basePath = os.environ['RAM_SVN_DIR']\n"
core/src/Logging.cpp:128:    fs::path root(getenv("RAM_SVN_DIR"));
core/test/src/TestPythonConfigNodeImp.cxx:32:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
core/test/src/TestPythonConfigNodeImp.cxx:177:    std::string base = std::string(getenv("RAM_SVN_DIR")) + "/packages/core/";
core/test/src/TestPythonConfigNodeImp.cxx:192:    std::string filepath = std::string(getenv("RAM_SVN_DIR"))
core/test/src/TestApplication.cxx:39:    bf::path root(getenv("RAM_SVN_DIR"));
core/test/src/TestDependencyGraph.cxx:27:    bf::path root(getenv("RAM_SVN_DIR"));
logging/test/src/TestEventPlayer.cxx:48://     boost::filesystem::path root(getenv("RAM_SVN_DIR"));
python/ram/gui/util/__init__.py:18:__lib_path = __path.join(__os.environ['RAM_SVN_DIR'],'build','packages',
python/ram/test/main.py:18:if not os.environ.has_key('RAM_SVN_DIR'):
vision/src/LCHConverter.cpp:268:    std::string baseDir(getenv("RAM_SVN_DIR"));
vision/src/LCHConverter.cpp:282:    std::string baseDir(getenv("RAM_SVN_DIR"));
vision/src/BuoyDetector.cpp:47:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestCamera.cxx:29:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestSafeDetector.cxx:30://    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestBinDetector.cxx:42:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestBinDetector.cxx:48:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestImage.cxx:26:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestSegmentationFilter.cxx:24:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestDuctDetector.cxx:30:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestFANNSymbolDetector.cxx:30:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestFANNSymbolDetector.cxx:37:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestPipeDetector.cxx:31:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestFANN.cxx:37:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestFANN.cxx:44:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestChecks.cxx:32:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/Utility.cxx:35:    boost::filesystem::path root(getenv("RAM_SVN_DIR"));
vision/test/src/TestVelocityDetector.cxx:31://    boost::filesystem::path root(getenv("RAM_SVN_DIR"));

Removing scripts/setenv is finding another solution to these tests. The two ways I've seen of doing this are:

1) Just use the current working directory. Tests will fail if they're run out of the wrong directory. 2) Find the top level directory through a different way. This can be through just looking for a specific file/directory. Python does this in its working tree by looking for Modules/Setup. After being installed, it does it by looking for os/path.py. This can be through something like looking for the .git directory, which wasn't previously possible since SVN sprinkles .svn directories everywhere.

rpath is already used for binaries. I forgot about this when I was originally talking with @jwonders.

virtualenv doesn't work that way. It takes advantage of how Python itself find libraries. virtualenv automatically generates some scripts to make using it easier, but all that's required is you use the version of Python in the generated tree structure that virtualenv makes. Your bash environment does not need to be changed at all.

jlisee commented 11 years ago

Glad to see your better CMake build system mitigates most of the issues. I would go for the approach you listed of trying to find the root directory dynamically, but I would wrap it up in a function like "std::string ram::findTreeRoot()".

As for virtualen, requiring the user to use a specially generated script to use your special environment is quite similar to have a script setup that envrionment in the first place. I use an extension called virtualenvwrapper which automatically switches which special python interp you are using, it does mess with shell variables.

jwonders commented 11 years ago

If I remember correctly, you can specify a working directory for tests within CMake / CTest. This would allow us to use relative paths where RAM_SVN_DIR is used in the tests. Finding the root dynamically is probably the easiest way to deal with the uses in python unless you want to have CMake generate a header file with a macro for the directory and then wrap a function for python.