I am using MSBuild and I came across this topic called Targets that lets you perform some tasks before building the project.
I need to run a C++ function which is present in a .cpp file in my (.sln) solution file. I came across this example to run a task, but it is written in C#.
using System;
using Microsoft.Build.Utilities;
namespace SimpleTask1
{
public class SimpleTask1: Task
{
public override bool Execute()
{
// This is where the task would presumably do its work.
return true;
}
}
}
So basically, I want run a C++ function before the building my solution file and I am confused on how to use MSBuild tasks and targets for this purpose. This C++ function actually generates some code that is necessary for successful building, else the build would fail.
Related
I'm trying to create a small application that will be able to communicate with the AWS IoT service. Since I want it to be fairly small and I wanted to try something new, I decided to go for Kotlin Native. I quickly noticed that AWS has released their C++ library that allows you to easily connect to the AWS IoT service (https://github.com/aws/aws-iot-device-sdk-cpp/tree/release) I downloaded it and even managed to compile with MinGW (yes, I'm on Windows). I noticed that it generated a bunch of *.o files. I reckon this is now the right time to import it to my Kotlin Native project. My build.gradle file for now looks completely standard
plugins {
id 'kotlin-multiplatform' version '1.3.11'
}
repositories {
mavenCentral()
}
kotlin {
targets {
// For ARM, preset should be changed to presets.iosArm32 or presets.iosArm64
// For Linux, preset should be changed to e.g. presets.linuxX64
// For MacOS, preset should be changed to e.g. presets.macosX64
fromPreset(presets.mingwX64, 'mingw')
configure([mingw]) {
// Comment to generate Kotlin/Native library (KLIB) instead of executable file:
compilations.main.outputKinds('EXECUTABLE')
// Change to specify fully qualified name of your application's entry point:
compilations.main.entryPoint = 'sample.main'
}
}
sourceSets {
// Note: To enable common source sets please comment out 'kotlin.import.noCommonSourceSets' property
// in gradle.properties file and re-import your project in IDE.
mingwMain {
}
mingwTest {
}
}
}
task runProgram {
def buildType = 'release' // Change to 'debug' to run application with debug symbols.
dependsOn "link${buildType.capitalize()}ExecutableMingw"
doLast {
def programFile = kotlin.targets.mingw.compilations.main.getBinary('EXECUTABLE', buildType)
exec {
executable programFile
args ''
}
}
}
for some reason I cannot find any examples as to how to add my freshly complied dependency. Normally when you code C++ you have to specify the path to Include directory and the Lib directory separately. AFAIK this is not something that gradle provides out of the box. How can I import this dependency then? Or perhaps there's some centralised repository I could simply pull such dependency from, like in pretty much every other programming language that is still used nowadays? At least this specific library doesn't seem to be available on NuGet :/
Kotlin/Native is not[1] interoperable with C++ at this moment. You can however create C wrapper for any C++ library and it's functions from Kotlin/Native[2].
When using multiplatform gradle plugin you can define native interop with this syntax:
kotlin {
linuxX64 { // Replace with a target you need.
compilations.main {
cinterops {
myInterop {
// Def-file describing the native API.
// The default path is src/nativeInterop/cinterop/<interop-name>.def
defFile project.file("def-file.def")
// Package to place the Kotlin API generated.
packageName 'org.sample'
// Options to be passed to compiler by cinterop tool.
compilerOpts '-Ipath/to/headers'
// Directories for header search (an analogue of the -I<path> compiler option).
includeDirs.allHeaders("path1", "path2")
// Additional directories to search headers listed in the 'headerFilter' def-file option.
// -headerFilterAdditionalSearchPrefix command line option analogue.
includeDirs.headerFilterOnly("path1", "path2")
// A shortcut for includeDirs.allHeaders.
includeDirs("include/directory", "another/directory")
}
anotherInterop { /* ... */ }
}
}
}
}
If you only define the interop name the plugin will look for .def file[3] in src/nativeInterop/cinterop/ directory and use it (in this case src/nativeInterop/cinterop/myInterop.def).
kotlin {
linuxX64 {
compilations.main {
cinterops {
myInterop {
}
}
}
}
}
The .def files[3] contains information about the library you are trying to use and typically look like this.
headers = png.h
headerFilter = png.h
package = png
More information about cinterop: https://kotlinlang.org/docs/reference/native/c_interop.html
More information about multiplatform projects: https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html
I've been trying to figure out a proper way of leveraging the information already present in a solution file of a rather big c++ code base.
The problem I'm trying to solve is calling an external script on some of the project files within the solution, but observing the already present dependencies specified in the solution and single project files.
I've successfully called said (python) script by adding a custom target to one of my project files and using msbuild with the /t:{TargetName} command on the vcxproj file.
I could now add this target to every project file that needs to call this script and afterwards call msbuild for each of them in the correct order, however this defeats the purpose of leveraging the dependencies known by the solution.
Calling the solution with the custom target does however not work (as seen by other stackoverflow questions like this: Invoke Custom MSBuild Target on Solution File).
On the other hand, since I want to be able to ONLY call the script target and not being dependent on also calling some Build command, I cannot use the proposed workarounds in some of those answers of adding a Post or PreBuild target.
Is there any other way of using the dependencies without having to go the route of msbuild and custom targets, or is there an other workaround that could serve my purpose?
Is there any other way of using the dependencies without having to go the route of msbuild and custom targets, or is there an other workaround that could serve my purpose?
You can build the sln programmatically, Here is a console APP with c# for your reference.
using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Framework;
using Microsoft.Build.Logging;
using System;
namespace LoadAllProject
{
class Program
{
static void Main(string[] args)
{
ILogger logger = new ConsoleLogger();
string solutionPath = #"D:\Project\Msbuild\CppApp5\CppApp5.sln";
var solutionFile = SolutionFile.Parse(solutionPath);
foreach (var item in solutionFile.ProjectsInOrder)
{
Project project = ProjectCollection.GlobalProjectCollection.LoadProject(item.AbsolutePath);
project.SetGlobalProperty("Configuration", "Debug");
if (project.GetPropertyValue("RootNamespace") == "CppApp5")
{
project.Build(new[] { "Build", "Yourcustomtarget" }, new[] { logger });
}
else
{
project.Build(new[] { "Build" }, new[] { logger });
}
}
Console.ReadKey();
}
}
}
I would like to visualize the code flow for a C++ project that I need to modify. The code compiles and runs fine.
Background:
Actually I am modifying an MRI sequence code. The framework is being called idea (SIEMENS). It somehow combines visual studio 2008 and cygwin to call customized command line inputs. Even the strucutre of makefile is different from usual makefile that I usually use for C++ project. (Disclaimer: I do not understand much about makefile and its customization nor do I know much about use of cygwin.)
1) I have access to dll and .so files
2) Also, path to include files are somehow abbreviated.
Abbreviated include statement:
#include "MrServers/MrMeasSrv/SeqIF/csequence.h"
Full include statement
#include "C:/MIDEA/N4_VD13A_LATEST_20120616/n4/pkg/MrServers/MrMeasSrv/SeqIF/csequence.h"
3) My project does not start with main(); but, it starts with init() and then it pass to prep(), check(), run(). Prep stage becomes particularly complicated.
4) The IDEA framework is designed in combination with cygwin for command line use only. So, I can not place break point.
Could someone suggest me how to visualize the code flow?
I am running my first program in ubuntu.
But there was an error when I tried to run it:
public class HelloWorld {
public native String nativeHelloWorld();
static {
System.loadLibrary("HelloWorld");
}
public void print(){
{
String str = nativeHelloWorld();
System.out.println(str);
}
}
public static void main(String[] args) {
(new HelloWorld()).print();
return;
}
}
this error was found :
Exception in thread "main" java.lang.UnsatisfiedLinkError:HelloWorld.nativeHelloWorld()Ljava/lang/String;
how can I solve this error?
For Running JNI program in android, You should look at steps described here, You will need to build the native code using this command
cd <ndk-root>/samples/hello-jni
<ndk_root>/ndk-build
After successful build you will get the .so file in this directory,
\hello-jni\libs\armeabilib\hello-jni.so
Assuming you are trying to execute HelloJNi sample program from SDK. Once you got that file in libs directory, Run the project using eclipse simple run button and you will have your HelloWorld :).
These lines taken from Getting Stated JNI from SUN site
Make sure that the native library resides in one of the directories in
the native library path. If you are running on a Solaris system, the
LD_LIBRARY_PATH environment variable is used to define the native
library path. Make sure that it includes the name of the directory
that contains the libHelloWorld.so file. If the libHelloWorld.so file
is in the current directory, you can issue the following two commands
in the standard shell (sh) or KornShell (ksh) to set up the
LD_LIBRARY_PATH environment variable properly:
LD_LIBRARY_PATH=.
export LD_LIBRARY_PATH
I have set up a project on top of Qt (so source is written in C++) and I wanted to try Gradle for automatic builds on that. It took me some time to get into the details of configuring a multi project build (there is an executable and two libs) and now I am trying to tell the cpp-exe and the cpp-lib plugin how my source tree is structured.
I have set up a task that should print all of the source sets (there should be at least the default ones right?) and it looks like this:
task projectinfo {
description = "Informations about the current project"
group = INFORMATIONS_GROUP
doFirst {
task -> print ("""${task.project.sourceSets.all}""")
}
If I run this task Gradle tells me that there is no property "sourceSets" for the project. The documentation of the plugin tells me that it is possible to customize the source locations, but not how.
So my question would be: How can I tell the Gradle cpp plugin which source files to use. If there is any documentation about the cpp plugin apart from its API documentation and the Gradle user guide that would be helping too.
Have a look at Adam Murdoch's usage of Gradle's 'cpp plugin'. I believe he's one of the main Gradle submitters, so he should know how to use this better than anyone:
Exert from native-platform/build.gradle
cpp {
sourceSets {
main {
source.exclude 'curses.cpp'
}
curses {
source.srcDirs = ['src/main/cpp']
source.include 'curses.cpp'
source.include 'generic.cpp'
source.include 'generic_posix.cpp'
}
}
}
Then, within the 'libraries' node, refer to all/any combination of architecture and source sets:
sourceSets << cpp.sourceSets.main
sourceSets << cpp.sourceSets.curses
I've not had too long to look over it myself, but it looks like he defines a number of OS architecture based source code include combinations and stores these in the variants variable. He then processes them into platform JARs (I haven't actually ran the build yet, maybe I should).
Also, take a look at https://github.com/rklaren/GradleJNI, it uses the cpp plugin but looks to be a little Windows-oriented.
Update - I also found https://github.com/alkemist/gradle-cpp-demo, which has an example of the 'cpp-exe' plugin building an executable.