craftr-build / craftr-build-4.x

Frontend for the Craftr build framework.
https://craftr-build.github.io/craftr/
Other
60 stars 14 forks source link

Example in README.md didn't work for me #137

Closed winksaville closed 7 years ago

winksaville commented 7 years ago

After following the install instructions (I used pip to install py-nr and craftr from the checked our sources) I tried the example. My manifest.json is:

(venvpy3) wink@wink-desktop:~/prgs/test-craftr
$ cat manifest.json 
{
  "name": "myapp",
  "version": "1.0.0",
  "dependencies": {
    "lang.cxx": "*",
    "lib.cxx.curlpp": "*"
  },
  "options": {
    "debug": {
      "type": "bool"
    },
    "outbin": {
      "type": "string",
      "default": "main"
    }
  }
}

My Craftrfile is:

(venvpy3) wink@wink-desktop:~/prgs/test-craftr
$ cat Craftrfile 
load_module('lang.cxx.*')
load_module('lang.cxx.curlpp.*')

program = cxx_binary(
  inputs = cpp_compile(
    sources = glob(['src/*.cpp']),
    defines = ['MYAPP_DEBUG'] if options.debug else [],
    frameworks = [cURLpp]
  ),
  output = options.outbin
)

I then ran craftr export:

(venvpy3) wink@wink-desktop:~/prgs/test-craftr
$ craftr export
lang.cxx: loading "lang.cxx.clang" (with lang.cxx.clang.toolkit="")
lang.cxx:   cxc.name="gcc"
lang.cxx:   cxc.target_arch="x86_64-pc-linux-gnu"
lang.cxx:   cxc.version="6.2.1"
Traceback (most recent call last):
  File "/home/wink/venvpy3/bin/craftr", line 11, in <module>
    load_entry_point('craftr-build', 'console_scripts', 'craftr')()
  File "/home/wink/foss/craftr/craftr/__main__.py", line 378, in main_and_exit
    sys.exit(main())
  File "/home/wink/foss/craftr/craftr/__main__.py", line 374, in main
    return commands[args.command].execute(parser, args)
  File "/home/wink/foss/craftr/craftr/__main__.py", line 203, in execute
    module.run()
  File "/home/wink/foss/craftr/craftr/core/session.py", line 514, in run
    exec(code, vars(self.namespace))
  File "/home/wink/prgs/test-craftr/Craftrfile", line 2, in <module>
    load_module('lang.cxx.curlpp.*')
  File "/home/wink/foss/craftr/craftr/defaults.py", line 199, in load_module
    'in the dependencies'.format(module.ident, name))
RuntimeError: "myapp-1.0.0" can not load "lang.cxx.curlpp", make sure that it is listed in the dependencies

I checked an I do have curl installed on my system:

$ which curl
/usr/bin/curl
(venvpy3) wink@wink-desktop:~/prgs/test-craftr
$ curl --version
curl 7.51.0 (x86_64-pc-linux-gnu) libcurl/7.51.0 OpenSSL/1.0.2j zlib/1.2.8 libssh2/1.8.0
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets 

I think there needs to be something simpler, like a hello world example.

winksaville commented 7 years ago

First attempt at a hello world example. It didn't work:

$ rm -rf build/
(venvpy3) wink@wink-desktop:~/prgs/test-craftr
$ ls -al
total 12
drwxr-xr-x 1 wink users   54 Nov 28 14:05 .
drwxr-xr-x 1 wink users 1624 Nov 28 11:03 ..
-rw-r--r-- 1 wink users  179 Nov 28 13:58 Craftrfile
-rw-r--r-- 1 wink users   62 Nov 28 13:59 hw.c
-rw-r--r-- 1 wink users  219 Nov 28 11:46 manifest.json
(venvpy3) wink@wink-desktop:~/prgs/test-craftr
$ cat manifest.json 
{
  "name": "hw",
  "version": "1.0.0",
  "dependencies": {
    "lang.cxx": "*"
  },
  "options": {
    "debug": {
      "type": "bool"
    },
    "outbin": {
      "type": "string",
      "default": "main"
    }
  }
}
(venvpy3) wink@wink-desktop:~/prgs/test-craftr
$ cat Craftrfile 
load_module('lang.cxx.*')

program = cxx_binary(
  inputs = cpp_compile(
    sources = ['hw.c'],
  ),
  output = options.outbin
)
(venvpy3) wink@wink-desktop:~/prgs/test-craftr
$ craftr export
lang.cxx: loading "lang.cxx.clang" (with lang.cxx.clang.toolkit="")
lang.cxx:   cxc.name="gcc"
lang.cxx:   cxc.target_arch="x86_64-pc-linux-gnu"
lang.cxx:   cxc.version="6.2.1"
(venvpy3) wink@wink-desktop:~/prgs/test-craftr
$ craftr build
ninja: error: '/home/wink/prgs/test-craftr/build/hw.c', needed by '/home/wink/prgs/test-craftr/build/hw-1.0.0/obj/*.o', missing and no known rule to make it

I then realized the problem was I needed to have the full path so I changed Craftrfile to set its sources to glob(['hw.c']) and it worked:

$ cat Craftrfile 
load_module('lang.cxx.*')

program = cxx_binary(
  inputs = cpp_compile(
    sources = glob(['hw.c'])
  ),
  output = options.outbin
)

But output is build/hw-1.0.0/main, I'd rather have it called hw and put it in the root:

load_module('lang.cxx.*')

program = cxx_binary(
  inputs = cpp_compile(
    sources = glob(['hw.c']),
  ),
  output = '/home/wink/prgs/test-craftr/hw'
)

I'd like to have the notion of "project root" directory something like this This might already exist and this probably isn't very "pythonic" but I think you get the idea:

load_module('lang.cxx.*')

def prj_root(srcs):
  """Take a parameter that is a string or a list of string
  and appends the the project dir on to the front.

  If the parameter is a single string it returns a single string
  and if its a list it returns list of strings.
  """

  import os

  # getcwd() returns ./build/ to get its parent use dirname()
  # Need a better way to gurantee we always get the 'project dir'
  prj_dir = os.path.dirname(os.getcwd())

  if isinstance(srcs, str):
    ret_path = os.path.join(prj_dir, srcs)
    return ret_path
  elif isinstance(srcs, list):
    ret_list = []
    for src in srcs:
      ret_list.append(os.path.join(prj_dir, src))
    return ret_list

program = cxx_binary(
  inputs = cpp_compile(
    sources = prj_root(['hw.c']),
  ),
  output = prj_root('hw')
)
NiklasRosenstein commented 7 years ago

Hey Wink,

it should have been load_module('lib.cxx.curlpp.*') instead of lang.cxx..., a typo. Anyway, I've simplified the example in the README to not load any dependencies and just compile some .cpp files. I will need to implement #134 before cURL and cURLpp will compile on Linux and Mac OS. Also the pkg-config loader is not yet implemented, otherwise YES it should just work with cURL installed globally with your package manager (see #131).


Regarding your second post: Craftr 2 behaves the same as Craftr 1 in that it changes to the build directory before any build scripts are executed. So any relative path you type and not explicitly convert to an absolute path is relative to the build directory, in this case hw.c.

In Craftr 1 there was path.local() which has been replaced by simply local() so you write

program = cxx_binary(
  inputs = cpp_compile(
    sources = [local('hw.c')],
  ),
  output = local('hw')  # Only use local() if you want the output binary in your working tree
)

There's also the project_dir builtin which points to the root of your project. There's some information on the Builtins Documentation but there still needs to be added a lot of documentation text. :)

NiklasRosenstein commented 7 years ago

Btw. you can use the following to create another target that runs your program.

run = gentarget([[program]], explicit=True)

Then use

$ craftr export
$ craftr build run
winksaville commented 7 years ago

Thanks, local() is just fine and run worked OK, but its verbose for something that should be common. I suggest something like:

run = runtarget(program)

or

runtarget = program

How do I setup a clean target?

Also, when I modify my Craftrfile and do a craftr export followed immediately by a craftr build ninja reports there is nothing to do, this should be easier. In meson they automatically do the update of the build.ninja that would be a nice feature for the future.

winksaville commented 7 years ago

I suggest deleting "Depending on the availability, the cURLpp library will be compiled from source or the flags will be retrieved with pkg-config (TODO). To build the project, use" from the example in README.md and adding the "runtarget" and then change craftr build to craftr build run or add craftr run and then mention craftr build run which will build and run in one step. (I assume command line options following run, craftr run a b c, will be passed to main()?)

Also mention where the executable is as ./build/hw-1.0.0/main isn't obvious.

NiklasRosenstein commented 7 years ago

I suggest deleting "Depending on the availability, the cURLpp library will be compiled from source or the flags will be retrieved with pkg-config (TODO). To build the project, use" from the example in README.md

Yes I forgot to remove it in the previous commit, the current example doesn't even use cURL anymore.

I suggest something like:

run = runtarget(program)

The gentarget() thing is a workaround as I haven't thought of a good name yet. In Craftr 1 you used to import craftr.ext.rules and use rules.run(). I like runtarget() though.

Thanks, local() is just fine and run worked OK, but its verbose for something that should be common.

You're right, it's rather common. However, that is the design I chose for Craftr from the very beginning. Every path is relative to the build tree by default, otherwise you need to use something to select exactly which path you want to use. If you want a path relative to your project directory, use local('path..') or glob(['pattern1', 'pattern2', ...]). Note that if you want to use local() on multiple paths, there's a trick with map().

sources = map(local, ['foo.c', 'bar.c'])

How do I setup a clean target?

Currently not available, I am still thinking about the best way to add it. My current preference is to use a special clean command like craftr clean [target, [target, [...]]].

and then change craftr build to craftr build run or add craftr run and then mention craftr build run which will build and run in one step. (I assume command line options following run, craftr run a b c, will be passed to main()?)

craftr build accepts zero or more target names on the command line, additional arguments will not be passed to main() but are instead also interpreted as targets to build. If you want to pass additional arguments, currently you need to add them to gentarget().

run = gentarget([[main, "foo", "bar"]], explicit=True)

Or with the runtarget() I will add

run = runtarget(main, "foo", "bar")

Also mention where the executable is as ./build/hw-1.0.0/main isn't obvious.

You're right, it isn't obvious. That's how craftr organizes the build tree. I'll add this info.

Thanks for your input, Wink.

winksaville commented 7 years ago

Thanks