Managing a scala project with a Makefile - scala

First of all, I know how to write a basic/intermediate level
makefile. In my c++ projects I use a makefile that does a lot of stuff
automatically. The most important to me is that it automatically
detects all source files (which are always in the same folder) using
wildcards, uses that to predict the name (and location) of all object files, and compiles appropriately.
Recently I've been trying to achieve the same effect with my scala
projects, but I've hit two obstacles.
Copilled class files which belong to packages are stored inside
subdirectories (like com/me/mypack/). This is a problem because
Make needs to find these files to check the timestamps (and I
have no idea how to do that automatically).
Some source files (such as those defining a package object)
generate class files with different naming standards. Again, Make
needs to know where these class files are and I don't know how to
do that automatically.
The consequence of this is that the "problematic" source files are
recompiled every time I run make (which is aggravated by scala's long
compile times). I'd like to know how to fix that without having to
manually write out the entire list of expected class files.
EDIT As an extra note: I'd like to avoid placing the source files in subdirectories. I like keeping them all in the same directory for several reasons.

You should use sbt or Maven for Scala. These are designed specifically for the way Scala and Java work, and they will be much easier to set up and use. They also provide many more features than make does.
These tools are used for a variety of things. Compiling is a big one, but they are also important for dependency management. Also, sbt (and probably Maven?) does "incremental compilation", so that only classes that have changed are recompiled, which speeds up compilation.
I personally use sbt, but I know people who prefer Maven.

Related

Assemble transitive closure of a main file in scala sbt project

I'm working on a scala sbt project, and I am at a point where I want to assemble the whole thing to share a .jar-file with others, so that they can use it on their side. For my local testing, I'm doing so using the sbt-assembly plugin, that works nicely.
When sharing, I would though prefer to only share the parts that are important for the other party (the project has huge components that irrelevant at the current point, and I'd prefer not to share these for various reasons). Concretely, they will be executing one particular main file, so it would be enough to pack everything that this file depends on.
Is there a way to accomplish this? I'd also be interested in doing this on the code level (i.e., create a copy of the project that only contains dependencies of that main file), but also while assembling or even modifying the jar file after assembly is okay. I did not find the tools to achieve any of these.
As I said, I'm dealing with a scala sbt project, and I'm working with IntelliJ IDEA; I'd also be happy with an IDE tool that does the job.

Output folder of the Kotlin compiler in Eclipse

The Jetbrains Kotlin compiler in Eclipse outputs to a hidden folder inside the Eclipse compiler plugin. This hidden folder is then made available through the Eclipse Kotlin classpath container.
In bndtools we need a normal file system folder since bnd can run both from the file system as well as in Eclipse. Since the folder is a linked resource there is no known way to translate it outside Eclipse.
Anybody knows how to tell the Kotlin compiler to just output it in the bin folder?
Currently, this is not possible in the Kotlin Eclipse plugin.
To make it possible that Kotlin code can be used from Java, Kotlin plugin produce so-called lightweight class files to this folder. These class files do not contain bodies for methods and they are stored in memory.
Actual class files, that are used to run an application, are being built only before launch and they are produced to the default output folder. For now, we cannot produce class files on each save reasonably fast as there is no incremental compilation in the plugin yet:
Feel free to upvote for this issue.
From the short analysis of the code of Kotlin plugin, it looks like the proper method is KotlinCompiler.compileKotlinFiles. It is being called in two contexts:
KotlinBuilder.build — this is the one called on the project build; it makes a call stack trick (or rather a hack...) to check if being called from the LaunchConfigurationDelegate, and depending on the results, either compiles whole project (via its own private fun compileKotlinFiles), or just makes stubs in memory.
KotlinCompilerUtils.compileWholeProject — this is in fact being called from 1.; nice static method, perfect for abuse until the problem is correctly solved in the plugin. :)
So, I'd use the method from 2. wrapped in a similar way as compileKotlinFiles from file in 1.

How to stop IntelliJ Idea from changing package declarations when moving or copying Scala files

Unlike Java, Scala does not require the location of a file to correspond to the file's package declaration - e.g. a file in the package com.company.project need not be in com/company/project. My company's Scala projects have a directory structure that does not correspond to their package structure, and the Scala compiler is quite happy with this.
However, when moving or copying a Scala file, IntelliJ automatically changes the file's package declaration to match its location. To work around this, I have to either manually revert the change or use a separate tool to do these file operations.
Is there a way to disable this behaviour?
(This question is related but doesn't describe the exact behaviour I'm talking about.)
This is not currently possible. A request for this feature has been opened on JetBrains YouTrack here.

Importing source files and folders into IAR Workbench

I have a cup of source files in a certain folder structure in my file system. I want to use this structure for a project in the IAR Workbench. Thinking of Eclipse, that could be so easy! But in the IAR Workbench, the folders will become to "Groups", which are only kind of virtual folders. The Workbench doesn't care about folders.
Is there some easy and fast way to import them?
Up to now I have to add the groups manually each and then add the files to the groups, and that's really annoying!
Is there maybe a tool to generate a proper project file (*.ewp) out of a file/folder structure path?
This would help me a lot!
You should have a look at IAR Project/Add Project Connection command.
Although IAR doesn't seem to have any public documentation on the xml syntax, or at least I couldn't find any, you can find Infineon DAVE (Config.xml) and Freescale PE (ProjectInfo.xml) files if you search around. These can be used as examples to figure out the syntax on how to write your own xml files in one of these interfaces, to allow you to specify where all your c, h, assembly and library files are from where ever they may be in your file system. They also allow you to define preprocessor includes for compiler/assembler, and DAVE allows you to define a path variable, which is also very useful.
See: https://mcuoneclipse.com/2013/11/01/iar-arm-v6-7-comes-with-improved-processor-expert-support/
I have modified a DAVE Config.xml file and found it EXTREMELY useful for managing and migrating even just a handful of project files. For example to upgrade to a new release with all files having a new directory root, you just change a single line in the xml file (defining the new root), and all source files, compiler includes etc are all updated to the new level. No more manually editing the preprocessor includes or replacing all the files in the project. And no more fiddling around with ../../ file system hierarchy navigation stuff, you just specify directly (or indirectly via a path to) where the files are, no more relative from where your project happens to be. VERY NICE.
IAR should consider opening this up (documenting) for general users, as it is very useful for project management and migration. While at it they should also consider generalizing the xml syntax a little bit and allow for definition of IAR group heading names, specifying linker file name, and definitely allowing multiple xml files to be included (connected) (so that subprojects can be easily added or removed without effecting the other subproject definition files) and a few basic things like that.
If they where to do a bang up job on this, they might consider allowing most/all aspects of IAR project configuration that might be required by the subproject, to be defined in these xml files, and then entire (sub)projects could just be plopped down anywhere and be up an running extremely quickly (OK, just let me dream a bit :)
For anyone who happens upon this you may want to check out https://github.com/IARSystems/project-migration-tools. They have a tool for pulling in file trees here.

Should I put my output files in source control?

I've been asked to put every single file in my project under source control, including the database file (not the schema, the complete file).
This seems wrong to me, but I can't explain it. Every resource I find about source control tells me not to put generated output files in a source control system. And I understand, it's not "source" files.
However, I've been presented with the following reasoning:
Who cares? We have plenty of bandwidth.
I don't mind having to resolve a conflict each time I get the latest revision, it's just one click
It's so much more convenient than having to think about good ignore files
Also, if I have to add an external DLL file in the bin folder now, I can't forget to put it in source control, as the bin folder is not being ignored now.
The simple solution for the last bullet-point is to add the file in a libraries folder and reference it from the project.
Please explain if and why putting generated output files under source control is wrong.
You haven't explained what "the database file" is.
I would certainly include 3rd party libraries in source control, as they're necessarily for the build and it's good to have a way of reproducing a build at a later time with the library versions you used at that particular moment. But yes, those libraries should be included from a "libraries" folder rather than the output directory.
I wouldn't generally include my own libraries built from the sources elsewhere in the same repository - although I have been in situations where that's been worth doing, where some projects didn't use the "latest and greatest" version of a common library, but just occasionally updated.
The most important practical argument I'd give against including everything, in a world where disk, processor and network are considered free and instantaneous, is that it makes it harder to tell what really changed for any given commit. It's easier to look down a list of 3 source files than 3 source files and 150 binaries from the obj/bin directories.
Generated output files (in general) are "dangerous" in a VCS because:
what you need to version is how to regenerate them: the day you will need to actually update them, chances are you won't remember how to do it
they can contain some private generated file which make them work on the committer desktop, but not on a client one ("works on my machine" TM syndrome)
some generated file are not easily stored in delta (binary especially), making them consuming lots of space (and the topic of cleaning that space will come-up someday...)
External libraries are not generated directly by your project, and can be put in a VCS, although external repositories like a public Maven repo are better at this kind of management.
Do we also put compiled object files such as class files, executables, DLLs build from our source? What about when we're doing serious volume testing and that database becomes many gigabytes or terabytes in size?
The clue is in the name: it's Source Code Management System.
I can understand the simplicity of put eveything in, it's more likely that developer doesn't forget some important file. But if you're doing regular automated builds then surely that gets picked up anyway?
I think the key phrase is here:
It's so much more convenient than
having to think about good ignore
files
Are you explicitly forbiden from having good ignore files? My guess is that already you are excluding .exe and .class (or whatever) files. Suppose you did take the trouble to exclude your database would that be a problem? Why? It's a concious action that you are chosing to take for the commone good. In Eclipse it's a couple of seconds work to add a new file type to the workspace's CVS ignore rules for all projects.
A rule of "No Ignore Files" is almost self-evidently absurd. Once you have the freedom the have some ignore files then why not just use them intelligently to exclude the DB? Who is inconveninced? Only yourself, if anyone, and you're prepared to do the extra work.