Build and run an executable locally with Conan - cmake

Say I have a simple hello world project in CMake that creates a binary under bin.
I build it with Conan using the latest CMake module.
In the conanfile.py, is this package method enough to announce the executable?
def package(self):
cmake = CMake(self)
cmake.install()
Then, if I want to build the project and run the executable locally, but in Conan's context, which commands should I type?

The package method you've defined will use the installation structure defined by cmake.install() to define the package structure. For example, if your cmake.install() method installs binaries to the bin directory, the bin directory will be present in the package folder in your conan cache, i.e. ~/.conan/data/<package>/<version>/<user>/<channel>/package/<package_id>/bin.
This alone is enough to run the executable locally - you can execute it from the above path, put it onto your PATH - whatever you need. It's not convenient though. To add some convenience, you can use the VirtualRunEnv generator to consume executables. To illustrate with cmake:
$ conan install cmake/3.22.4# --build=missing -g VirtualRunEnv
This will install cmake 3.22.4 into your local cache, and generate the following files in your cwd:
.
├── conanrunenv-release-x86_64.sh
├── conanrun.sh
├── deactivate_conanrunenv-release-x86_64.sh
└── deactivate_conanrun.sh
You can use this in the same way you would a python virtual environment:
$ source conanrun.sh
$ which cmake
/home/user/.conan/data/cmake/3.22.4/_/_/package/5c09c752508b674ca5cb1f2d327b5a2d582866c8/bin/cmake
And to restore the environment:
$ source deactivate_conanrun.sh
Restoring environment
$ which cmake
/usr/bin/cmake
The second method is to use the deploy generator:
$ conan install cmake/3.22.4# --build=missing -g deploy
This will grab cmake and all of it's dependencies from the conan cache and dump them to your cwd. After running this command, the directory looks like the following:
.
├── cmake
│   ├── bin
│   │   ├── ccmake
│   │   ├── cmake
│   │   ├── cpack
│   │   └── ctest
│   ├── licenses
│   │   └── Copyright.txt
│   └── share
│   ├── aclocal
│   ├── bash-completion
│   ├── cmake-3.22
│   ├── emacs
│   └── vim
├── deploy_manifest.txt
└── openssl
├── bin
│   ├── c_rehash
│   └── openssl
├── include
│   └── openssl
├── lib
│   ├── cmake
│   ├── libcrypto.a
│   └── libssl.a
└── licenses
└── LICENSE
You can then move this wherever you need to and put it on your system PATH if you so desire. The same principle would apply to your package - create the recipe in the local cache, and use generators to consume it.
To illustrate:
Place your package in the conan cache
$ conan create .
Consume it using VirtualRunEnv
$ conan install mypkg/0.1.0#user/channel --build=missing -g VirtualRunEnv
Consume it using deploy
$ conan install mypkg/0.1.0#user/channel --build=missing -g deploy
Instead of issuing conan install commands above, you can also list your package as a requirement in a conanfile.txt or conanfile.py for a consumer package, i.e. for a conanfile.py:
def requirements(self):
self.requires(mypkg/0.1.0)
self.requires(someotherpkg/1.2.0)
And then you can use the virtual environment generators to collect environment information for all dependencies. In the directory containing the conanfile.py:
$ conan install . -g VirtualRunEnv
Hope this helps.
References:
VirtualRunEnv generator
deploy generator
Mastering Conan Virtual Environments
virtualrunenv generator (deprecated, I believe)
Conan generators

Related

WiX dotnet publish Cant find csproject file

I'm new to WiX and I'm trying to follow this tutorial on publishing a .msi file (I'm at 1h and 20m into the video)and every time I try to run the dotnet publish from my visual studio project file which has an Exec Command line in it, I get this error:
Severity Code Description Project File Line Suppression State
Error The system cannot find the file specified. (Exception from HRESULT: 0x80070002) HelloWorld.Installer light.exe 0
Here is the complete output
dotnet publish ..\HelloWorld\HelloWorld.csproj -c Debug -r win-x86
1> Microsoft (R) Build Engine version 17.0.0+c9eb9dd64 for .NET
1> Copyright (C) Microsoft Corporation. All rights reserved.
1> Determining projects to restore...
1> Nothing to do. None of the projects specified contain packages to restore.
1> \\Mac\Home\Desktop\M\HelloWorld\packages\WiX.3.11.2\build\..\tools\candle.exe -dDebug -d"DevEnvDir=C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\\" -dSolutionDir=\\Mac\Home\Desktop\MainDirectory\HelloWorld\ -dSolutionExt=.sln -dSolutionFileName=HelloWorld.sln -dSolutionName=HelloWorld -dSolutionPath=\\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld.sln -dConfiguration=Debug -dOutDir=bin\Debug\ -dPlatform=x86 -dProjectDir=\\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld.Installer\ -dProjectExt=.wixproj -dProjectFileName=HelloWorld.Installer.wixproj -dProjectName=HelloWorld.Installer -dProjectPath=\\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld.Installer\HelloWorld.Installer.wixproj -dTargetDir=\\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld.Installer\bin\Debug\ -dTargetExt=.msi -dTargetFileName=HelloWorld.Installer.msi -dTargetName=HelloWorld.Installer -dTargetPath=\\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld.Installer\bin\Debug\HelloWorld.Installer.msi -dHelloWorld.Configuration=Debug -d"HelloWorld.FullConfiguration=Debug|AnyCPU" -dHelloWorld.Platform=AnyCPU -dHelloWorld.ProjectDir=\\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld\ -dHelloWorld.ProjectExt=.csproj -dHelloWorld.ProjectFileName=HelloWorld.csproj -dHelloWorld.ProjectName=HelloWorld -dHelloWorld.ProjectPath=\\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld\HelloWorld.csproj -dHelloWorld.TargetDir=\\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld\bin\Debug\ -dHelloWorld.TargetExt=.dll -dHelloWorld.TargetFileName=HelloWorld.dll -dHelloWorld.TargetName=HelloWorld -dHelloWorld.TargetPath=\\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld\bin\Debug\HelloWorld.dll -out obj\Debug\ -arch x86 -ext \\Mac\Home\Desktop\MainDirectory\HelloWorld\packages\WiX.3.11.2\build\..\tools\\WixUIExtension.dll Components.wxs Directories.wxs Product.wxs
1> \\Mac\Home\Desktop\MainDirectory\HelloWorld\packages\WiX.3.11.2\build\..\tools\Light.exe -out \\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld.Installer\bin\Debug\en-us\HelloWorld.Installer.msi -pdbout \\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld.Installer\bin\Debug\en-us\HelloWorld.Installer.wixpdb -cultures:en-us -ext \\Mac\Home\Desktop\MainDirectory\HelloWorld\packages\WiX.3.11.2\build\..\tools\\WixUIExtension.dll -loc Common.wxl -contentsfile obj\Debug\HelloWorld.Installer.wixproj.BindContentsFileListen-us.txt -outputsfile obj\Debug\HelloWorld.Installer.wixproj.BindOutputsFileListen-us.txt -builtoutputsfile obj\Debug\HelloWorld.Installer.wixproj.BindBuiltOutputsFileListen-us.txt -wixprojectfile \\Mac\Home\Desktop\MainDirectory\HelloWorld\HelloWorld.Installer\HelloWorld.Installer.wixproj obj\Debug\Components.wixobj obj\Debug\Directories.wixobj obj\Debug\Product.wixobj
1>light.exe(0,0): error LGHT0001: The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
Here is the line I'm running in my project file in the Before Build:
<Exec Command="dotnet publish ..\HelloWorld\HelloWorld.csproj -c $(Configuration) -r win-$(Platform)" />
I am not sure but I believe the error means that it cant find the .csproj file to publish.
My project tree is:
├── HelloWorld
│   ├── App.cs
│   ├── Command.cs
│   ├── HelloWorld.addin
│   ├── HelloWorld.csproj
│   ├── Properties
│   │   └── AssemblyInfo.cs
│   ├── SyncManager32.png
│   ├── bin
│   │   └── Debug
│   │   ├── HelloWorld.dll
│   │   └── HelloWorld.pdb
│   └── obj
│   └── Debug
│   ├── DesignTimeResolveAssemblyReferences.cache
│   ├── DesignTimeResolveAssemblyReferencesInput.cache
│   ├── HelloWorld.csproj.AssemblyReference.cache
│   ├── HelloWorld.csproj.CoreCompileInputs.cache
│   ├── HelloWorld.csproj.FileListAbsolute.txt
│   ├── HelloWorld.dll
│   ├── HelloWorld.pdb
│   └── TempPE
├── HelloWorld.Installer
As you can see from the tree, it should work with the Exec Command="dotnet publish ..\HelloWorld\HelloWorld.csproj -c Debug -r win-x86 " because it just has to go up one folder level, then into HelloWorld and find the .csproj file but for some reason, it's not finding it.
I'm running on my Macbook pro with executing this command on Visual Studio in my Parallels remote desktop.
I've been at this for a couple of days and can't figure it out. Any help/and or direction is appreciated! let me know if I can add any additional information that could be helpful.
I figured it out. It looks like when I opened the project, I opened it from "This PC", therefore visual studio / the dotnet publish command was reading it from my \mac\Home\etc drive and thus wasn't able to find the same drive. ie, on Command-Line, you can cd to \mac\home\etc. Parallels had my entire mac on a Y drive.
I closed visual studio and then opened up the project from the Y drive and ran the command and it worked.

Simple way to add a Premake subproject inside a CMake project?

I use CMake for my C++ projects and I like to have my dependencies as Git submodules inside a third-party folder so I can have easy access to the code and the possible CMake targets I can link with.
.
├── CMakeLists.txt
├── src
│   └── main.cpp
└── third-party
└── CMakeSubmodule # OK
└── CMakeLists.txt # OK
My root CMakeLists.txt would typically contain :
add_subdirectory(src)
add_subdirectory(third-party/CMakeSubmodule)
target_link_libraries(myTarget PRIVATE SubmoduleTarget)
Now, I want to add a submodule that only uses premake :
.
├── CMakeLists.txt
├── src
│   └── main.cpp
└── third-party
└── PremakeSubmodule # !
└── premake5.lua # !
How would you do to simply add the submodule as a dependency ?
Do I have to manually convert all premake files to CMakeLists.txt ?
A convenient solution would allow to directly link to a target as follow, so I don't have to manually set the correct include directories and link to the lib files :
target_link_libraries(myTarget PRIVATE PremakeTarget) # Would be great

Is there any way to link add_custom_command to a target defined in another directory with add_custom_target?

Because this is the standard structure of a ROS workspace (robotics framework) I have the following two directories:
ros/
|── DIR_A
│   ├── CMakeLists.txt
│   ├── package.xml
│   ├── README.md
│   ├── setup.py
│   └── src
│   ├── some_code.cpp
|── DIR_B
│   ├── CMakeLists.txt
│   ├── package.xml
│   ├── README.md
│   ├── setup.py
│   └── src
│   ├── some_other_code.cpp
I am trying to add a custom target called clean_compiled that will run the make clean target of a specific external project (already works). But I also need to add a custom command to this clean target in the CMakeLists of another directory. This is what I have:
First CMakeLists.txt:
# We add the custom target
add_custom_target(clean_compiled
COMMENT "Cleaning compilation files in ${SOME_DESTDIR}"
COMMAND $(MAKE) clean PATH=${SOME_DESTDIR}
WORKING_DIRECTORY ${SOME_WORKING_DIRECTORY}
)
Second CMakeLists.txt:
# We try to add a custom command to this custom target
add_custom_command(TARGET clean_compiled
COMMENT "Cleaning compilation files in ${ANOTHER_DESTDIR}"
WORKING_DIRECTORY ${ANOTHER_WORKING_DIRECTORY}
COMMAND $(MAKE) clean PATH=${ANOTHER_DESTDIR}
)
When I run make clean_compiled for the whole repository, I get this warning:
TARGET 'clean_compiled' was not created in this directory.
This warning is for project developers. Use -Wno-dev to suppress it.
And the custom_command is never called.
Is there any way to link the custom command to the target in the other directory without causing circular dependencies?
add_custom_command is pretty clear that it only works with targets in the same directory. There is no way around this. So the second rule cannot be a custom command and needs to be a custom target, for example called clean_another_dest_dir.
https://discourse.cmake.org/t/create-target-that-only-runs-other-target/885/6
You can use add_dependencyto make custom targets depend on other custom targets and make them run, add_dependencies(clean_another_dest_dir clean_compiled), but that isn't always what you want.
Another option is a custom target that runs all the other custom targets.
add_custom_target(clean_all_dir
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR } --target clean_compiled
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR } --target clean_another_dest_dir
)

how to attach a task to run after the tasks from a plugin in gradle

I have installed the detekt plugin in gradle-kotlin with
plugins {
id("io.gitlab.arturbosch.detekt").version("1.10.0")
}
This yields tasks for me when I run tasks:
Verification tasks
------------------
check - Runs all checks.
detekt
detektBaseline - Creates a detekt baseline on the given --baseline path.
detektGenerateConfig - Generate a detekt configuration file inside your project.
detektMain - EXPERIMENTAL & SLOW: Run detekt analysis for main classes with type resolution
detektTest - EXPERIMENTAL & SLOW: Run detekt analysis for test classes with type resolution
test - Runs the unit tests.
This generates checkstyle xml files. Unfortunately, I am forced to use teamcity, and in order to display the results of detekt in teamcity, it wants all the xml files to be rolled up into a zip file.
So my thought is that for each subproject, I want to run a task that copies the detekt output into a toArchive folder under the subproject's name, and then after detekt has run against ALL subprojects, I want to run the zip task.
The subprojects are each their own top level folder, per gradle practices:
$ tree -L 2
.
├── build
│   └── kotlin
├── build.gradle.kts
├── config
│   └── detekt
├── gradle
│   └── wrapper
├── gradlew
├── gradlew.bat
├── jobs
│   ├── build
│   ├── build.gradle.kts
│   └── src
├── lib
│   ├── build
│   ├── build.gradle.kts
│   └── src
├── README.md
├── settings.gradle.kts
└── SETUP.md
But I can't even begin to see how to do this.
I don't really care where the output folder is. I was gonna do the toArchive folder at the top level that is in the gradle zip tasks docs. But I don't think it matters much.
I am new to gradle and I find it very confusing.

How do I setup a Minecraft Forge development environment?

I want to start creating awesome Minecraft mods, and it seems that the current way to do so is with Minecraft Forge. I already got Gradle and the JDK installed, but no matter what I do I can't seem to get anything to build.
How can I get a Forge development environment working?
After downloading the Forge Mod Development Kit (MDK) archive, it should contain the following files:
forge-somewhere/
├── build.gradle
├── CREDITS-fml.txt
├── eclipse
├── forge-1.10.2-12.18.1.2073-changelog.txt
├── gradle
│   └── wrapper
│   ├── gradle-wrapper.jar
│   └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── LICENSE-new.txt
├── MinecraftForge-Credits.txt
├── Paulscode IBXM Library License.txt
├── Paulscode SoundSystem CodecIBXM License.txt
├── README.txt
└── src
└── main
├── java
│   └── com
│   └── example
│   └── examplemod
│   └── ExampleMod.java
└── resources
└── mcmod.info
In the README.txt there are instructions on how to set it up, but to put it simple, open a console/terminal in forge-somewhere and run gradle setupDecompWorkspace. It should set up a development environment and then you should be able to run gradle build normally. Note that you have to re-run setupDecompWorkspace for every mod you want to develop/compile.
If you're not using an IDE, or the command fails because of heap memory, you can use gradle setupDevWorkspace instead. This doesn't decompile Minecraft, so you won't be able to check the sources (which you can't without an IDE or something anyway), but it doesn't use nearly as much RAM, which is useful if you're on a lower-end system.
Simple:
Once you have downloaded the Forge .zip for the version that you plan on using, go to the same directory as your "gradlew.bat" file, hold shift-rightclick and open the command prompt.
Type:
gradlew.bat setupDecompWorkspace eclipse
Or if you're running with Intellij Idea (Which I recommend):
gradlew.bat setupDecompWorkspace idea
After that, it'll set up the Workspace as well as the correct coding software package that you wish to be using.