I'm a bit of an newb' to Ada. I see the following error when compiling a spec file on its own:
gcc -c shapes.ads
cannot generate code for file shapes.ads (package spec)
gnatmake: "shapes.ads" compilation error
The code works when it's build with the body and I can run a program that uses the package.
So what's the problem?
This isn't really an error. (Yeah, I know it looks like one :-)
The way GNAT works is that the object code for a unit (package spec and body, and any "is separates") is placed in a single, ".o", object code file. So you get the object code file when you compile the body--the compilation of which automatically brings in the spec--but not the spec alone.
An exception is when the spec doesn't require a body, i.e., it contains no declarations, such as subprograms or tasks, that require bodies.
The .ads file only contains the specification of a package. If it requires a body, you can't compile it that way. You have to compile the .adb file.
Think of it like a C header (.h) file. You don't compile them either, only the .c files.
PS: you can use gnatmake, it should automatically resolve dependencies and compile what's needed.
Related
I've been struggling all afternoon to track down an issue with the Qt VS Tools in Visual Studio 2013. I'm trying to update an existing .vcxproj file that used a home-grown mechanism for generating MOC, UIC, etc. files to use the Qt VS Tools mechanism instead.
The problem I'm having is in the MOC command that's getting generated for .h files that include the Q_OBJECT macro. A sample line (reduced for brevity) is here:
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-I$(QTDIR)\include\QtGui" "-I$(NOINHERIT)"</Command>
The problem is that NOINHERIT doesn't exist, so the "-I$(NOINHERIT)" gets evaluated to "-I" without a value, and the MOC compiler complains and doesn't generate the MOC file. I've tried cleaning up inherited paths, checking and unchecking the "Inherit from parent or project defaults", and the only change I sometimes see is that it has "-I" without the NOINHERIT macro.
Completely starting over with a new .vcxproj file is beginning to feel like my only hope, but that's a much larger task than I'd like to take since there's a significant number of them with interdependencies that I'd rather not create again.
I'm using the latest Qt VS Tools, which is version 2.3.2. Any ideas on how to resolve this?
Naturally, five minutes after I post, I found the issue. An included property file had this:
<AdditionalIncludeDirectories></AdditionalIncludeDirectories>
Rather than this, which solved the problem:
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
Interestingly, and for what it's worth, this did not work:
<AdditionalIncludeDirectories />
Add the %(AdditionalIncludeDirectories) at project->C/C++ -> General -> Additional Include Directories.
%(AdditionalIncludeDirectories) is added by default, but if for some reason, this is overwrite by mistake, then we will get an error as such.
Moc'ing XXXXXXX.h...
Missing value after '-I'.
I have a module I wrote here:
# Hello.jl
module Hello
function foo
return 1
end
end
and
# Main.jl
using Hello
foo()
When I run the Main module:
$ julia ./Main.jl
I get this error:
ERROR: LoadError: ArgumentError: Hello not found in path
in require at ./loading.jl:249
in include at ./boot.jl:261
in include_from_node1 at ./loading.jl:320
in process_options at ./client.jl:280
in _start at ./client.jl:378
while loading /Main.jl, in expression starting on line 1
There is a new answer to this question since the release of Julia v0.7 and v1.0 that is slightly different. I just had to do this so I figured I'd post my findings here.
As already explained in other solutions, it is necessary to include the relevant script which defines the module. However, since the custom module is not a package, it cannot be loaded as a package with the same using or import commands as could be done in older Julia versions.
So the Main.jl script would be written with a relative import like this:
include("./Hello.jl")
using .Hello
foo()
I found this explained simply in Stefan Karpinski's discourse comment on a similar question. As he describes, the situation can also get more elaborate when dealing with submodules. The documentation section on module paths is also a good reference.
EDIT: Updated code to apply post-v1.0. The other answers still have a fundamental problem: if you define a module and then include that module definition in multiple places, you will get unexpected hard-to-understand errors. #kiliantics' answer is correct as long as you only include the file once. If you have a module that you're using across multiple files, make that module into a package, use add MyModule, and then type using MyModule in as many places as you want, letting Pkg handle module identity for you.
Though 张实唯's answer is the most convenient, you should not use include outside the REPL (or just once per included file as a simple practice to organize large modules, as in the first example here). If you're writing a program file, go through the trouble of adding the appropriate directory to the LOAD_PATH. Remy gives a very good explanation of how to do so, but it's worth also explaining why you should do so in the first place. (Additionally from the docs: push!(LOAD_PATH, "/Path/To/My/Module/") but note your module and your file have to have the same name)
The problem is that anything you include will be defined right where you call include even if it is also defined elsewhere. Since the goal of modules is re-use, you'll probably eventually use MyModule in more than one file. If you call include in each file, then each will have its own definition of MyModule, and even though they are identical, these will be different definitions. That means any data defined in the MyModule (such as data types) will not be the same.
To see why this is a huge problem, consider these three files:
types.jl
module TypeModule
struct A end
export A
end
a_function.jl
include("types.jl")
module AFunctionModule
using ..TypeModule
function takes_a(a::A)
println("Took A!")
end
export takes_a
end
function_caller.jl
include("a_function.jl")
include("types.jl") # delete this line to make it work
using .TypeModule, .AFunctionModule
my_a = A()
takes_a(my_a)
If you run julia function_caller.jl you'll get MethodError: no method matching takes_a(::A). This is because the type A used in function_caller.jl is different from the one used in a_function.jl. In this simple case, you can actually "fix" the problem by reversing the order of the includes in function_caller.jl (or just by deleting include("types.jl") entirely from function_caller.jl! That's not good!). But what if you wanted another file b_function.jl that also used a type defined in TypeModule? You would have to do something very hacky. Or you could just modify your LOAD_PATH so the module is only defined once.
EDIT in response to xji: To distribute a module, you'd use Pkg (docs). I understood the premise of this question to be a custom, personal module. It's also fine for distribution if you know the relative path of the directory containing your module definition from each file that needs to load that module, e.g. if all your files are in the same folder then you'd just have push!(LOAD_PATH, #__DIR__).
Incidentally, if you really don't like the idea of modifying your load path (even if it's only within the scope of a single script...) you could symlink your module into a package directory (e.g. ~/.julia/v0.6/MyModule/MyModule.jl) and then Pkg.add(MyModule) and then import as normal. I find that to be a bit more trouble.
This answer has been OUTDATED. Please see other excellent explanations.
===
You should include("./Hello.jl") before using Hello
This answers was originally written for Julia 0.4.5. There is now an easier way of importing a local file (see #kiliantics answer). However, I will leave this up as my answer explains several other methods of loading files from other directories which may be of use still.
There have already been some short answers, but I wanted to provide a more complete answer if possible.
When you run using MyModule, Julia only searches for it in a list of directories known as your LOAD_PATH. If you type LOAD_PATH in the Julia REPL, you will get something like the following:
2-element Array{ByteString,1}:
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/local/share/julia/site/v0.4"
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/share/julia/site/v0.4"
These are the directories that Julia will search for modules to include when you type using Hello. In the example that you provided, since Hello was not in your LOAD_PATH, Julia was unable to find it.
If you wish to include a local module, you can specify its location relative to your current working directory.
julia> include("./src/Hello.jl")
Once the file has been included, you can then run using Hello as normal to get all of the same behavior. For one off scripts, this is probably the best solution. However, if you find yourself regular having to include() a certain set of directories, you can permanently add them to your LOAD_PATH.
Adding directories to LOAD_PATH
Manually adding directories to your LOAD_PATH can be a pain if you wish to regularly use particular modules that are stored outside of the Julia LOAD_PATH. In that case, you can append additional directories to the LOAD_PATH environment variable. Julia will then automatically search through these directories whenever you issue an import or using command.
One way to do this is to add the following to your .basrc, .profile, .zshrc.
export JULIA_LOAD_PATH="/path/to/module/storage/folder"
This will append that directory onto the standard directories that Julia will search. If you then run
julia> LOAD_PATH
It should return
3-element Array{ByteString,1}:
"/path/to/module/storage/folder"
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/local/share/julia/site/v0.4"
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/share/julia/site/v0.4"
You can now freely run using Hello and Julia will automatically find the module (as long as it is stored underneath /path/to/module/storage/folder.
For more information, take a look at this page from the Julia Docs.
Unless you explicitly load the file (include("./Hello.jl")) Julia looks for module files in directories defined in the LOAD_PATH variable.
See this page.
I have Julia Version 1.4.2 (2020-05-23). Just this using .Hello worked for me.
However, I had to compile the Hello module before just using .Hello. It makes sense for both the defined and using scripts of Hello is on the same file.
Instead, we can define Hello in one file and use it in a different file with include("./Hello.jl");using .Hello
If you want to access function foo when importing the module with "using" you need to add "export foo" in the header of the module.
We are experiencing a bizarre random behavior of the LESS compiler at the Windows Command Line. We are getting inconsistent syntax error messages like we were missing variables or mixins declarations. The thing is, if we LESS compile the same file a second time, the compiler works just fine and we get our beautiful CSS file. The same files work just fine using the client side less.js while running our solution in Visual Studio.
Some more details:
LESS compiler (less#1.4.0-b4) at the Windows7 Command Line.
Here is what I type on command line:
lessc --include-path="site/Css" Css\results-imports.less > fileoutput.comb.css --yui-compress
results-imports.less has a list of less files that should be imported and compiled into css files, some of the less files have nested imports as well.
we get errors like: NameError: variable #brand-color-14 is undefined in C:\Css\loadmask.less. This is one of the imported less files #brand-color-14 is declared in one of the less files that should have been imported before loadmask.less
I'm trying to get package references resolved during a build, using GNAT Programming Suite (hosted on Win XP). In the Builder Results, I get errors like this one:
file "ac_configuration_s.ada" not found
Clicking on the error takes me to a line like this:
with
Ac_Configuration,
Dispense_Timer,
...
The first item (Ac_Configuration) isn't resolved, but the second item (Dispense_Time) is resolved. I have several others that do or don't resolve. All of the files in question (spec and body) are identified as source files.
When I hover my mouse over the line with the error, a popup shows up that offers this:
(Cross-references info not up to date. This is a guess.)
Ac_Configuration
local package declared at D_Ac_Config_S.Ada:85
The guess is correct, but I don't know how to use this. How do I get this to correctly build?
Update
Here is teh call to gcc
gcc -c "-gnatec=C:\Source\build\GNAT-TEMP-000001.TMP" -I- -gnatA
-x ada "-gnatem=C:\Source\build\GNAT-TEMP-000002.TMP" "C:\Source\C_Cbt_Main_B.Ada"
I don't see a reference to teh "miimal" switch.
In this case, there is no corresponding body file file D_Ac_Config_S.Ada. So the is no body file to compile separately.
When I right click on the package reference inside the with, I can goto the declaration of Ac_Configuration and every other package name that is the source of an error. So these lreferences are being resolved somehow.
By the way, I have not used ADA before, so I'm still trying to understand everything.
It looks as though you're using _s.ada as the suffix for specs, and I'm guessing _b.ada for bodies?
GNAT may have difficulty with this naming convention. It's possible, using a GNAT Project file (.gpr), to alter GNAT's default convention ({unit-name}.ads for specs, {unit-name}.adb for bodies) but the rules (see "Spec_Suffix") say "It cannot start with an underscore followed by an alphanumeric character" (I haven't tried this, but you can see that it would confuse the issue if you had a package Foo_S, for example).
LATER: It turns out that GNAT (GPL, 4.7, 4.8) is quite happy with your suffixes!
If the package Ac_Configuration is really a local package declared at line 85 of D_Ac_Config_S.Ada, then there's your problem; you can only with a library unit, which in this case would be D_Ac_Config.
with D_Ac_Config;
...
package Foo is
...
Bar : D_Ac_Config.Ac_Configuration.Baz;
I wonder whether D_Ac_Config_S.Ada (for example) actually contains multiple Ada units? (if so, compiling that file should result in a compilation error such as end of file expected, file can have only one compilation unit). GNAT doesn't support this at compile time, providing instead a utility gnatchop.
Would it be possible to just gnatchop all the source and be done with it?
Hm, I think it sounds like the compiler's got a bad set of objects/ALIs it's working with, hence the cross-reference not up to date error. (Usually the compiler's good about keeping things up to date; but you may want to check to see if the "minimal recompilation" switch is set for the project.)
Have you tried compiling just the ["owning"] file D_Ac_Config_S.Ada? (i.e. if it were a spec, go to the corresponding body and compile that.) That should force its ALI/object files to be updated.
Then try building as normal.
-- PS: you might have to clean first.
While I used to compile a single source file with Cmd+K in prior versions of Xcode, how does one do the same in Xcode 4? (Note that this is different than preprocessing or showing the disassembly of the file.) If compiling from a command line is proposed then it must be such that the project's settings, include paths, preprocessor definitions, etc., are all included.
An example use case is where I make a header file change but only want to test the change's effect with respect to a single source file, not all of the files that depend upon that header.
The command has been moved to the Perform Action submenu. Look under
Product > Perform Action > Compile filename.cpp
To assign Cmd+K to it, go to
File > Preferences > Key Bindings > Product Menu group
and you'll find Compile File where you can assign a key. Cmd+K is assigned to Clear Console now by default, so be sure to remove that binding to avoid conflicts.
One way that I have found to do this is to using the following menu commands:
Product -> Generate Output -> Generate Preprocessed File
Product -> Generate Output -> Generate Assembly File
This may not be exactly what you want, but it will compile the single file.
When you build a project, xcode runs compilation command. You can check the log, search for your file and copy paste that command on Terminal. It'll compile only the file for which you copy/pasted on the terminal.
If your file is C (or C++) file, then simply open your terminal, go to the folder in which the file resides and type
gcc -o outputFile inputFile.c
I am not familar with Objective-c that much, but GCC might work since it's only a superset of C, just like C++.
Hope that was helpful :)
The keyboard shortcut Cmd+K on Xcode 3 and before has been remapped to Cmd+B on Xcode 4
Along the same lines, Cmd+Return was remapped to Cmd+R (in case you ever used that)
The common requirement for single file compilation is checking it for syntax errors. (atleast for me). Since xcode4 highlights syntax errors as you type. It seems apple removed that feature.