I was attempting to make a "library" type of project in dart and then "depend" on that library from another project (all using the path dependency functionality of the yaml file). I understand that I might be able to get the dependency stuff to work if I hosted my library or if I used GIT, but I don't want to do either, because I feel that pure filesystem based dependencies should be a "no brainer".
So, without further adieu, here is my situation. I have a very simple dart library/project based on web_ui that contains two files:
esrvdartui.dart
---------------
library esrvdartui;
import 'dart:html';
import 'package:web_ui/web_ui.dart';
part 'esrvradiobutton.dart';
esrvradiobutton.dart
--------------------
part of esrvdartui;
class ESrvRadioButton extends RadioButtonInputElement
{
ESrvRadioButton ()
{
}
}
I then created another very small/simple web_ui based project called "ExampleForm" that wants to use my esrvdartui project above. Both of these projects exist in the same directory structure. My ExampleForm project contains the following yaml file:
pubspec.yaml
------------
name: ExampleForm
description: A sample WebUI application
dependencies:
js: any
browser: any
web_ui: any
esrvdartui:
path: ../esrvdartui
No matter what I set my path to in the above yaml file, I never see my web\packages directory underneath of my ExampleForm project get updated with my files from the esrvdartui project and as such, I cannot use the files in my library using the file based dependency method, because the build fails for my ExampleForm project.
"Pub install" does not complain with the above path and it doesn't complain when I use an absolute path, so I know that "Pub install" see my dependent project. It just doesn't copy the darned files for me.
Any thoughts?
My pubspec.lock file for ExampleForm is:
# Generated by pub
# See http://pub.dartlang.org/doc/glossary.html#lockfile
{"packages":{"logging":{"version":"0.5.0+1","source":"hosted","description":"logging"},"source_maps":{"version":"0.5.0+1","source":"hosted","description":"source_maps"},"unittest":{"version":"0.5.0+1","source":"hosted","description":"unittest"},"pathos":{"version":"0.5.0+1","source":"hosted","description":"pathos"},"analyzer_experimental":{"version":"0.4.7+1","source":"hosted","description":"analyzer_experimental"},"web_ui":{"version":"0.4.6+1","source":"hosted","description":"web_ui"},"js":{"version":"0.0.21","source":"hosted","description":"js"},"csslib":{"version":"0.4.3","source":"hosted","description":"csslib"},"esrvdartui":{"version":"0.0.0","source":"path","description":{"relative":false,"path":"C:/Users/Jason/dart/esrvdartui"}},"html5lib":{"version":"0.4.3","source":"hosted","description":"html5lib"},"args":{"version":"0.5.0+1","source":"hosted","description":"args"},"browser":{"version":"0.5.0+1","source":"hosted","description":"browser"},"meta":{"version":"0.5.0+1","source":"hosted","description":"meta"}}}
My pubspec.lock file for esrvdartui is:
Generated by pub
See http://pub.dartlang.org/doc/glossary.html#lockfile
{"packages":{"meta":"version":"0.5.0+1","source":"hosted","description":"meta"},"browser":{"version":"0.5.0+1","source":"hosted","description":"browser"},"args":{"version":"0.5.0+1","source":"hosted","description":"args"},"html5lib":{"version":"0.4.3","source":"hosted","description":"html5lib"},"analyzer_experimental":{"version":"0.5.0+1","source":"hosted","description":"analyzer_experimental"},"csslib":{"version":"0.4.3","source":"hosted","description":"csslib"},"web_ui":{"version":"0.4.6+1","source":"hosted","description":"web_ui"},"pathos":{"version":"0.5.0+1","source":"hosted","description":"pathos"},"js":{"version":"0.0.22","source":"hosted","description":"js"},"source_maps":{"version":"0.5.0+1","source":"hosted","description":"source_maps"},"unittest":{"version":"0.5.0+1","source":"hosted","description":"unittest"},"logging":{"version":"0.5.0+1","source":"hosted","description":"logging"}}}
I finally got this to work, but for the life of me, I couldn't find this documented anywhere. All you have to do is create a project in the Dart IDE. Then, create a top level folder in that project called "lib" (blow all other directories away other than the top level "packages" folder). Now, create your main library's .dart file. Let's call it "mylibrary.dart". This contents of this file will look something like this:
mylibrary.dart
library mylibrary;
import 'dart:json';
part 'src/libraryfile1.dart';
Now, create a sub-directory underneath of "lib" to place your library's source files into. This can really be named anything, but I choose to name it "src". Place your libraryfile1.dart file there and it should look something like this:
src/libraryfile1.dart
part of hix_lib;
.
.
.
All import statements should always be placed in your top-level main library file: mylibrary.dart.
Now, in the project that you wish to use this file-based library in, you must add your "mylibrary" to your project's pubspec.yaml file and choose: "Source: path". On my machine, because all projects are in the same directory, my path simply points to: ../mylibrary
And that's all there is to do!!!!!
Related
I am trying to create a static library that contains Swift and C code, and exposes only a Swift interface. So the C code side should ideally not be exposed to the outside world. I can't seem to figure out the right way to do this without causing warnings or errors.
For the sake of simplification, I tried setting up a minimal Swift+C static library with these files:
Test.swift
class Test {
func test() -> CInt {
return testFromC()
}
}
Test.c
#include "Test.h"
int testFromC(void) {
return 0xdeadbeef;
}
Test.h
int testFromC(void);
What I want is a static library that exposes the Swift class Test, but not the C function testFromC(). I can live with it being exposed if there is no alternative, though.
What I have tried is:
Add a bridging header. This almost works, but a) lots of people say this is not supported or recommended, b) it exposes testFromC() to the importer of the module, and c) under some circumstances it throws warnings about implicitly importing the bridging header (which is true, but what I want is specifically to NOT do that).
Add a modulemap. I can't figure out how to do this. No examples online seem to work for me, and if anyone knows how to do this correctly, I would love to see an example for these three files.
Add a private modulemap - I gather this is what I want if I want to avoid exposing the C functions but I had even less success with this.
Is anyone able to put together the exact steps to make this trivial example build?
You can indeed create a private module map so that the C symbols are not exported, see https://clang.llvm.org/docs/Modules.html#private-module-map-files.
The bridging header would not work because you want to create a framework and not an application.
There are certainly several ways to set up the project, one of which would be: create a project with the corresponding module map settings in XCode.
The .modulemap file could look something like this:
framework module SwiftOnlyAPI {
umbrella header "SwiftOnlyAPI.h"
export *
module * { export * }
}
framework module SwiftOnlyAPI_Private {
header "Test.h"
}
Your Test.swift would rather look something like this:
import SwiftOnlyAPI_Private
public class Test {
public init() {
//perform some initializations
}
public func test() -> CInt {
return testFromC()
}
}
Please note a few small changes: the import of SwiftOnlyAPI_Private, this is necessary for the C functions that are not exported, but of course are called locally within the framework. Classes and exported methods must be public to be accessible from outside the framework.
Instructions
<File/New Project...> choose Framework, choose Language Swift name it SwiftOnlyAPI
add you files (.c,.h,.swift) to the SwiftOnlyAPI folder
select Test.h in the project navigator and switch the target membership in the inspector from Project to Private
choose SwiftOnlyAPI in the project navigator, select the SwiftOnlyAPI target
now click on Build Settings and for Mach-O Type select: Static Library
still in Build Settings: for Module Map File enter: SwiftOnlyAPI/SwiftOnlyAPI.modulemap
select the folder SwiftOnlyAPI in the SwiftOnlyAPI project, choose New File... from the context menu and, choose Empty template from the Other section and name it SwiftOnlyAPI.modulemap (uncheck target membership)
add the modulemap content shown above
A test produces the desired result, just as shown for the alternative solution for multiple targets below.
Static Library
Frameworks are really just either dynamic or static libraries (depending on the setting) with additional bundled files. Convenient for the framework users.
You can test this yourself with the file command:
Alternative
If you want to have the C part separate (e.g. for other consumers), you can also split it into two subprojects in an Xcode workspace, one for a static C lib and one for a static Swift-based framework:
create a XCode workspace <File/New Workspace...>, e.g. name it SwiftCWorkspace
<File/New Project...> choose Library, choose under Framework None (Plain C/C++ Library), name it MyCLib and choose type Static
in the dialog choose for Add to and Group: SwiftCWorkspace
select the MyCLib node in project navigator, choose New File... from the context menu and choose C file template, name it Test
replace the content with your Test.c and Test.h content
<File/New Project...> choose Framework, choose Language Swift name it SwiftOnlyAPI
in the dialog choose for Add to and Group: SwiftCWorkspace
select the folder SwiftOnlyAPI in the SwiftOnlyAPI project, choose New File... from the context menu and, choose Swift template and replace it with your ccontent
choose SwiftOnlyAPI in the project navigator, select the SwiftOnlyAPI target
now click on Build Settings and for Mach-O Type select: Static Library
still in Build Settings: for Module Map File enter: SwiftOnlyAPI/SwiftOnlyAPI.modulemap
now click on General and in the Frameworks and Library section add libMyCLib.a
select the folder SwiftOnlyAPI in the SwiftOnlyAPI project, choose New Group... from the context menu and name it MyCLib
drag & drop Test.h from MyCLib project to the MyCLib folder in SwiftOnlyAPI, uncheck Copy items if needed
with the newly linked file Test.h selected switch the target membership in the inspector from Project to Private
select the folder SwiftOnlyAPI in the SwiftOnlyAPI project, choose New File... from the context menu and, choose Empty template from the Other section and name it SwiftOnlyAPI.modulemap (uncheck target membership)
add the modulemap content shown above
Notes
If Xcode displays error messages even though you have set everything up correctly, it is occasionally necessary to exit Xcode after the project setup tasks, delete the ~/Library/Developer/Xcode/DerivedData folder, and then restart the build.
Test
import SwiftOnlyAPI
...
let result = SwiftOnlyAPI.Test()
print(result.test())
You can test this in a separate application using the SwiftOnlyAPI framework: the correct result will be output.
Also the C function testFromC is private and not externally accessible as desired, see screenshot:
I have some git libraries I am using for my app and using vscode. But I am a little unclear on how to reference these libraries and if I have to be specific in the 'from' part of not.
For example, my code below is something I copied from someone else code, and is at the top of my App.js file.
import {
Board,
BoardView,
} from 'cm-board';
Does vscode go search all subdirectories to find cm-board? Or, should I be using this instead:
import {
Board,
BoardView,
} from '../node-modules/cm-board';
And if I reference cm-board, does that also give me access to all files below cm-board too or do I have to import each one of those individually?
i want to locate the pathname for the image that i want to use in the project but i can't find the image.
I have tried giving like this '../images/logo.png', but it shows Module not found: Can't resolve './images/logo.png' in 'C:\Users\55590i5 D'\Desktop\react-website-v2-master\src\components'
the file i.e. logo.png to access is inside public->images->logo.png and i want to import it inside src->components->navbar.js.
You aren't going quite far up enough in the directory tree with that path. Starting from navbar.js, these would be the parts of the path:
../ (up to /components)
../ (up to src)
../ (up to the project root)
public
images
logo.png
so the full relative path would be ../../../public/images/logo.png.
However, if that's a create-react-app project, you can't import from public when you are inside src. Usually you would put an image you're trying to import somewhere under src (like in a src/assets folder, for example). See https://create-react-app.dev/docs/adding-images-fonts-and-files for more on this.
A foobar package
foobar
__init__.py
foo.py
bar
bar.py
Inside the __init__.py
from . import foo
from . import bar
Even though bar is not a package or a sub-package, it is still imported as a module (lolwut). I checked the import type by doing print(type(bar)) inside the __init__.py and it printed <class 'module'>... that's it. What's going on here? It is a module object, so I did print(dir(bar)) and the output was ['__doc__', '__loader__', '__name__', '__package__', '__path__', '__spec__']. Now, what's even more confusing to me is the __path__ variable in this. Isn't that a package-only thing?
Is this what's known as a namespace-package? I am thinking that it isn't, nevertheless I tried one more thing inside that __init__.py file - added a line import bar.bar. It ended in an ImportError. So, to sum up my question, what is this module useful for? Why did Python import this in the first place?
There's an amazing tutorial on this entire topic by David Beazley. I have watched the whole thing a while ago, but I guess I should watch it again to recollect everything.
From the docs
A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended. Within a module, the module’s name (as a string) is available as the value of the global variable __name__.
...
Packages are a way of structuring Python’s module namespace by using “dotted module names”. For example, the module name A.B designates a submodule named B in a package named A.
...
Packages support one more special attribute, __path__. This is initialized to be a list containing the name of the directory holding the package’s __init__.py before the code in that file is executed. This variable can be modified; doing so affects future searches for modules and subpackages contained in the package.
While this feature is not often needed, it can be used to extend the set of modules found in a package.
So yes, the __path__ variable is applied to the modules inside a package as well and those modules are treated as 'submodules of a package'
Edit
In Python 2.x, that package with the from . import bar would return an ImportError at that line. On Python 3.x the modulefoobar.foo has a type of <module 'foobar.foo' from '../py/foobar/foo.py'> and the foobar.bar of <module 'foobar.bar' (namespace)>.
Apparently, it appeared here
Regular packages will continue to have an init.py and will reside in a single directory. Namespace packages cannot contain an init.py
I am trying to include a miscellaneous library class from outside my app (it gets used by different apps).
My app is located at:
/var/www/websites/my_website/app/
And the class is located at:
/var/www/websites/libs/CakePHP/MyClass.php
In my bootstrap I'm struggling to figure out how to add the path for loading the classes from that directory:
App::build(array('Lib' => array('/var/www/websites/lib/')));
App::uses('MyClass', 'CakePHP');
$myClass = new MyClass();
Loading shouldn't be done in your bootstrap, but in your AppController's beforeFilter method instead.
Also, there is a reserved place for non-Cake libraries, being the app/Vendor directory. You can place all your classes in there and then load team easily with:
App::uses('MyClass', 'Vendor');
If it really needs to be in an alternative path, you need to specify and call the full path instead. And make sure to use the same names. Right now, you're specifying Lib, yet calling CakePHP as if that was a build by itself (which it's not). This won't work. It should look like this instead:
App::build(array('Lib' => array('/var/www/websites/lib')));
App::uses('MyClass', 'Lib/CakePHP'); // Define the subdirectory here
Also check the documentation on loading vendor files, it has quite some examples.