Skip to content

arduino commandline only full path accepted #1493

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

Closed
haobug opened this issue Jul 1, 2013 · 24 comments
Closed

arduino commandline only full path accepted #1493

haobug opened this issue Jul 1, 2013 · 24 comments
Assignees
Labels
Component: CLI The Arduino IDE's command line interface OS: OSX Specific to the Mac OS X (macOS) version of the Arduino IDE OS: Windows Specific to the Windows version of the Arduino IDE Type: Bug Upstream notified Related to a software component maintained by someone else. They have been notified of it
Milestone

Comments

@haobug
Copy link

haobug commented Jul 1, 2013

the .ino full path must be given.

either of following two will not work
$arduino some_proj.ino
$arduino ./some_proj.ino
it works only in this way.
$arduino pwd/some_proj.ino

my environment.
arduino version: downloaded from here http://downloads.arduino.cc/arduino-1.5.2-linux64.tgz
java version "1.7.0_21"
OpenJDK Runtime Environment (IcedTea 2.3.9) (7u21-2.3.9-0ubuntu0.12.04.1)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)

@cmaglie
Copy link
Member

cmaglie commented Jul 12, 2013

This seems a little bit complex to do, since the "arduino" shell script do a "cd $APPDIR" before starting the IDE, so from the Java side is impossible to obtain the original working directory (or maybe I'm missing something?).

Some possible solutions could be:

  • pass the working directory as first parameter from the shell script to the java side
  • modify the "arduino" shell script to not change directory (but this is not simple)

C

@matthijskooijman
Copy link
Collaborator

Why is not changing the current dir not simple? Because a lot of parts of the code assume a specific working directory? Or is there something fundamental?

@ffissore
Copy link
Contributor

Fixed. Will be available in tomorrow nightly build: http://arduino.cc/en/Main/Software#toc4

@matthijskooijman
Copy link
Collaborator

This is still broken on OSX (and possibly also Windows?). See https://groups.google.com/a/arduino.cc/d/msg/developers/Ci1Ood_UAxw/GRs_1wcZ_S0J

@matthijskooijman matthijskooijman added OS: Windows Specific to the Windows version of the Arduino IDE OS: OSX Specific to the Mac OS X (macOS) version of the Arduino IDE Component: CLI The Arduino IDE's command line interface and removed Component: IDE The Arduino IDE labels Sep 11, 2014
@wayoda
Copy link

wayoda commented Oct 3, 2014

@cmaglie

This seems a little bit complex to do, since the "arduino" shell script do a "cd $APPDIR" before starting the IDE, so from the Java side is impossible to obtain the original working directory (or maybe I'm missing something?).

There is a solution for this since java 1.5.

A java-class that is loaded from a jar can retrieve the location of its own jar-file on the filesystem. Here is a working code snippet taken from Stack Overflow

java,security.CodeSource codeSource = YourMainClass.class.getProtectionDomain().getCodeSource();
java.io.File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();

This piece of code works fine even if the path to the jar-file contains <SPACE> chars.

The "arduino" shell script needs to manualy switch the users working directory because processing.app.Base uses the System.property "user.dir" to locate the hardware and lib folders of the arduino distribution package.

The same functionality would be possible without touching the users working dir.

Class processing.app.Base could retrieve the location of pde.jar inside its own code and thereby also the root of the arduino distribution files.

There would be no need to do a cd "$APPDIR" inside the shell script and therefore no need to pass the extra --curdir parameter.

@matthijskooijman
Copy link
Collaborator

Ah, that sounds useful. If we can remove the --curdir hack, that would be nice.

On Windows, we can then perhaps remove the chdir option from the launch4j config and make it work there as well (see my post to the mailing list I linked above).

However, this does not really help on OSX where the java launcher insists on changing the directory IIRC. OTOH, I think the launcher used on OSX recently (1.5.8) changed, so perhaps the new launcher does have an option for this?

@wayoda
Copy link

wayoda commented Oct 3, 2014

Another approach to solve the problem on linux without changing too much in the java code, is to pass the $APPDIRvalue as an environment variable without doing a cd like this:

#FILE: build/linux/dist/arduino
#!/bin/sh

APPDIR="$(dirname -- "$(readlink -f -- "${0}")" )"

for LIB in \
    ${APPDIR}/java/lib/rt.jar \
    ${APPDIR}/java/lib/tools.jar \
    ${APPDIR}/lib/*.jar \
    ;
do
    CLASSPATH="${CLASSPATH}:${LIB}"
done
export CLASSPATH

LD_LIBRARY_PATH=${APPDIR}/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
export LD_LIBRARY_PATH

export PATH="${APPDIR}/java/bin:${PATH}"
export APPDIR

java -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel processing.app.Base "$@"

The method Base.getContentFile() would then request

String path = System.getenv("APPDIR");

instead of

String path = System.getProperty("user.dir");

and user.dir is untouched.by the application.

What about Windows ?

I had quick look at launch4j and I think the <chdir>.</chdir> could be left out when the classpath is specified using the %EXEDIR% prefix and the application dir is passed as an environment variable:

-DAPPDIR="%EXEDIR%"

@wayoda
Copy link

wayoda commented Oct 8, 2014

Running the IDE without changing the users working directory is possible on Linux and on Windows.

In its current state the IDE uses the System.Propertiy user.dir as the root-path from which all libraries and hardware specific files are searched. Thats why the startup files on windows and on linux have to change the working directory (user.dir) to the root of the arduino distribution.

In order to leave the user.dir property untouched we have to set the correct class- and library-path for the app on startup and we pass a new System.Property cc.arduino.appdirto the runtime which points to the root of the arduino distribution.

I tested this on a fork of the ide-1.5.x branch. (File links point to my fork)

Changes to the Java-Code

All occurences of the user.dir property are replaced with System.getProperty("cc.arduino.appdir")
app.src.processing.app.Base.java

Windows

File build\windows\launcher\config.xml needs to be updated

  • the <chdir></chdir>is set to the empty string because we don't want to change the user.dir any more.
  • the classpath entries are specified relative to the %EXEDIR% <cp>%EXEDIR%/lib/pde.jar</cp>
  • add a new System.Property <opt>-Dcc.arduino.appdir="%EXEDIR%"</opt>for the commandline.
  • remove the --curdir option (since we don't mess around with the users working dir any more)
Linux

File build/linux/dist/arduino needs to be updated.

  • remove the cd $APPDIRstatement
  • define CLASSPATH and LIBPATH relative to the value of APPDIR
  • pass a new System.Property -Dcc.arduino.appdir=${APPDIR}on the commandline.
  • remove the --curdir option (since we don't mess around with the users working dir any more)
MacOs

As far as I can see the user-dir property is not even used on the Mac version of the IDE as it uses the javaroot property in getContentFile().
Is there a Mac Developer out there who knows how this property relates to the users working dir?

@matthijskooijman
Copy link
Collaborator

Thanks for looking into this, looks like you did your homework well :-)

Changes to the Java-Code

The --curdir option and related stuff could be removed as well (probably in a separate commit, though).

the is set to the empty string because we don't want to change the user.dir any more.

Couldn't we just remove it altogether? Not sure if that would really have any advantages, though.

MacOs

Note that there are currently two versions of the OSX launching code, one for java6 (in the ide-1.5.x branch and one for java7 (in the ide-1.5.x-java7 branch). I'm not familiar with either one, though.

@ffissore
Copy link
Contributor

I've googled around once more and I can't find a working way of knowing current directory when using the Arduino binary from macosx. Tagging as "wontfix" and leaving open until working non hacks show up

@ffissore ffissore added the Type: Wontfix Arduino has decided that it will not resolve the reported issue or implement the requested feature label Apr 30, 2015
@wayoda
Copy link

wayoda commented May 1, 2015

I've googled around once more and I can't find a working way of knowing current directory when using the Arduino binary from macosx.

I wrote this little test application GetSystemPath.java for the commandline that reports the users current working dir, and the filesystem location of the jar file from which the little app is run.

Here is a link to a jar-file with that class
gsp.jar

Run this jar from anywhere on your filessystem

wayoda@shredder:~/dev/java/arduino-user-dir$ java -jar ~/bin/gsp.jar 
          Current user dir is : '/home/wayoda/dev/java/arduino-user-dir'
         Here is the jar-file : '/home/wayoda/bin/gsp.jar'
The directory of the jar-file : '/home/wayoda/bin'

If anybody could please try this on a Mac? Does it really fail on OSX???

Tagging as "wontfix" and leaving open until working non hacks show up

File jarDir=new File(GetSystemPath.class
                                    .getProtectionDomain()
                                    .getCodeSource()
                                    .getLocation()
                                    .toURI().getPath());

This is not a hack AFAIK.

@matthijskooijman
Copy link
Collaborator

@wayoda, it seems your example assumes running java directly, but on OSX Arduino uses an application launcher thingy AFAIK, that changes the current directory on startup (so I'd expect that your GetSystemPath thingy will then return the changed directory, not the original). I might be wrong, I've never actually used a Mac...

@wayoda
Copy link

wayoda commented May 1, 2015

OSX Arduino uses an application launcher thingy

So does windows (launch4j), but it is easy to fix this.

@matthijskooijman
Copy link
Collaborator

So does windows (launch4j), but it is easy to fix this.

What do you mean by "fix"? Stop using the launcher, or configure the launcher to not change the working dir? It seems that on OSX, the latter isn't possible (at least I couldn't find a way, looking at documentation only, last time I tried).

@wayoda
Copy link

wayoda commented May 1, 2015

There is an config file for the launch4j utillity that creates the windows exe in
build/windows/launcher/config.xml

The key <chdir>.</chdir> tells the application to set the user.dir the directrory where the exe lives.

From launch4j-config

<chdir>
Optional. Change current directory to an arbitrary path relative to the executable. If you omit this
property or leave it blank it will have no effect. Setting it to . will change the current dir to the same > > directory as the executable.
.. will change it to the parent directory, and so on.

@matthijskooijman
Copy link
Collaborator

Yeah, I can see how that would work on Windows. However, AFAIK (last time I checked, anyway) we don't use launch4j on OSX, but some Apple-provided launcher thing. Or did this change recently?

@wayoda
Copy link

wayoda commented May 1, 2015

The important function for all of this is processing.app.BaseNoGui.getContentFile(String name)that is used for looking up all the application resouces like the hardware path etc. For Linux and windows the function uses the artficially changed user.dir property and for the Mac it already uses .....

 static public File getContentFile(String name) {
    File path = new File(System.getProperty("user.dir"));

    if (OSUtils.isMacOS()) {
      if (System.getProperty("WORK_DIR") != null) {
        path = new File(System.getProperty("WORK_DIR"));
      } else {
        try {
          path = new File(BaseNoGui.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile();
        } catch (URISyntaxException e) {
          throw new RuntimeException(e);
        }
      }
    }

... the method I was proposing for the other platforms too.

So to me the only question is:

When I call the arduino-launcher-thingy on a Mac from the commandline is the user.dir property properly set to the users current directory?

@ffissore
Copy link
Contributor

The answer is "no": it's always set to user's HOME, despite the location of the app, despite your current directory when you launch it from a terminal

@wayoda
Copy link

wayoda commented May 12, 2015

The answer is "no": it's always set to user's HOME, despite the location of the app, despite your current directory when you launch it from a terminal

Thanks for testing, too bad!

Looks like OSX is simply broken in respect to the Java Documentation on user.dir: http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#getProperties()

@ffissore
Copy link
Contributor

Indeed :(

@ffissore
Copy link
Contributor

@ffissore ffissore added the Upstream notified Related to a software component maintained by someone else. They have been notified of it label May 19, 2015
@ffissore ffissore modified the milestones: Release 1.6.5, Release 1.6.6 Jun 15, 2015
@ffissore ffissore added the Help wanted Arduino would especially appreciate assistance from the community on this item label Jun 19, 2015
@ffissore
Copy link
Contributor

Please give a spin to #3421 as soon as bot has published it

@ffissore ffissore removed the Type: Wontfix Arduino has decided that it will not resolve the reported issue or implement the requested feature label Jun 25, 2015
@wayoda
Copy link

wayoda commented Jun 26, 2015

Linux version with #3421 pulled in compiles and runs fine.

@ffissore ffissore removed the Help wanted Arduino would especially appreciate assistance from the community on this item label Jun 26, 2015
@ffissore
Copy link
Contributor

I'm glad to say: fixes. Fix will be available in next hourly build http://www.arduino.cc/en/Main/Software#hourly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: CLI The Arduino IDE's command line interface OS: OSX Specific to the Mac OS X (macOS) version of the Arduino IDE OS: Windows Specific to the Windows version of the Arduino IDE Type: Bug Upstream notified Related to a software component maintained by someone else. They have been notified of it
Projects
None yet
Development

No branches or pull requests

5 participants