Visual Studio Code - interconnected environment variables - visual-studio-code

I am investigating how feasible would it be to switch to Visual Studio Code with larger and more complex projects in C++ with cmake and have hit the wall regarding environmental variables.
Some projects I'm dealing with require a complex structure of interconnected environmental variables, currently this is solved by mostly manual build in bash prompt
$ source envSetupFile
$ mkdir build && cd build
$ cmake .. && make -j $(nproc)
where the envSetupFile contains a lot of different variables, most cases related to toolchain and some specific settings. When those are just plain strings, everything works fine, however there are many cases of variables depending on another one, for example something like (in bash)
export PATH=/opt/custom/lib: $PATH
export ROOT=/some/path
export BIN=$ROOT/bin
export LIB=$ROOT/lib
what I did
I installed the c/c++ extension package along with CMake and CMakeTools packages plus EditorConfig for VS Code
and added custom lines to the visual studio config in the workspace:
/projectpath/.vscode/cmake-kits.json where I set the environmental variables, but while I can set (and verify) directly defined work, any that requires value of another fails completely.
example:
"environmentVariables":{
"POTATO": "aaa",
"CARROT": "bbb",
"CABAGE": "${POTATO}/${CARROT}"
}
I'd expect that afterwards when running cmake which references ${CABAGE} would resolve it as aaa/bbb, but instead of it it takes them as string literals and produces ${POTATO}/${CARROT} as ouptut
I must confess I'm a bit surprised by no trace of such use case in documentation or examples I've seen so far. Perhaps someone could lend a hand? (I'm running VisualStudio Code Version: 1.36.1 on ubuntu 16.04)

Related

How to set CMake parameter -j on Ubuntu

When building with CMAKE in two different codebases the option -j 16 is used, which tends to cause problems where -j 4 doesn't. Is there a global option for this? I can't find where to change it in Visual Studio Code CmakeTools.
Read this quickly before and admin deletes it :).
-j[cpu_count] is an argument to the generator (eg make) and as such can't be set by CMake in itself.
My advice is to either use eg Ninja (which handles this for you) or invoke CMake via a wrapper script that sets this depending on the codebase in question.
Eg in python3 f'-j{cpu_count()}'.

Cmake actions build for Windows x86

I have a Cmake/wxWidgets project that builds fine on my pc.
I compile wxWidgets using nmake /f makefile.vc BUILD=release TARGET_CPU=X86 and generate the CMake project using cmake .. -G "Visual Studio 16 2019" -A Win32 -DCMAKE_CONFIGURATION_TYPES=Release.
Like I wrote, this compiles fine on my pc. When I want to build it using a github action on Windows 2019 Image I first pull wxWidgets, compile it using the above statement, generate wxWidgets using the aboce statement and trigger the build using a cmd-script containing "%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\msbuild.exe" ".\build\NaCl-Configurator.sln" /p:Configuration=Release /p:Platform=Win32 /p:PlatformTarget=x86
But when doing this I always get the following error:
wxmsw31u_core.lib(corelib_wincmn.obj) : fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'x86' [D:\a\abc\abc\build\abc.vcxproj]
If I switch everything to x64 it compiles fine, but I need a x86 build. Is there any system setting I'm missing?
This is not an answer, this is a recommendation.
But after spending hours looking into your issue, I am seriously pulling my hair at the Microsoft documentation for MSBuild.
Just use Ninja. This is what we use to build our x64/x86 binaries.
You might need to learn a little bit about cmake toolchains, but at least you don't have to deal with this msbuild nonsense.
Ninja is faster, works much better with cmake, is a very tiny executable, etc.
Seriously using msbuild/visual-studio on your servers isn't worth it.
Again I apologize this isn't a direct answer to your question, if you do continue down this path I'm curious to see the answer.
====================================================
What I found out though:
I will say I'm very confused about the difference between PlatformTarget and Platform. Because all the visual studio solutions I generate don't even have PlatformTarget as a property anywhere. I scanned the generated solution files and didn't see this anywhere. Granted I'm using vs2019 so maybe it's deprecated I dunno.
Prefer to expand the /p -> /property that's just good practice for your build server scripts.
Perhaps try using the platform property "x86" instead. I literally couldn't find concrete information on which was preferred/correct. Win32/x86.
And as a final guess please start printing out your compiler, and toolchain information from cmake.
Resources:
How do I specify the platform for MSBuild?
https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-target-framework-and-target-platform?view=vs-2019
Me looking at the msbuild command line, and looking at my generated visual studio solutions.
I was using another github action to access nmake to build wxWidgets. Within this action I had to specify the architecture.
So using
- name: Preparing nmake
uses: ilammy/msvc-dev-cmd#v1
with:
arch: x86
- name: start building wx widgtes
run: |
cd ${{ env.WXWIN }}${{ env.wxMSW_VER }}\build\msw
nmake /f makefile.vc BUILD=release TARGET_CPU=X86
and then going on did the trick. It was only the with: arch: x86 that was missing

Getting an environment variable set in VSCODE based on CMake variant

I'm using Pybind11 to make C++/Python modules and apparently the output .DLLs need to be in the PYTHONPATH for the module to be imported (appending to sys.path does not work).
I'm using CMake variants to set various builds, and that makes separate output directories per variant.
I'm at a loss to find a way to set the PYTHONPATH environment variable in the integrated terminals (and jupyter notebooks) based on my chosen variant.
Any suggestions?
"terminal.integrated.env.windows": {
"PYTHONPATH": "${workspaceRoot}\\build\\${variant:platform}"
},
does not work (it doesn't seem to substitute ${variant:platform}).
in the .env file, neither ${workspaceRoot} nor ${variant:platform} seem to be available

How do I find what the Eclipse Cross Settings Prefix should be?

I have installed the latest version of Eclipse on my Windows 7 64-bit machine and the mingw compiler. In setting up a Hello World project, all goes well until I am asked for the Cross Settings what the Prefix is and the Path. The Path is obvious, it's the path to the compiler. However, I haven't the slightest idea what the Prefix is and Googling for much of the day hasn't enlightened me other than finding that a lot of other people have asked the question. Unfortunately the answers I've found appear to be for specific hardware. All I want to do is to produce an executable that will run on a Windows 32 bit or 64 bit machine.
So, what is the Prefix and how do I find what it should be?
What is probably happening here is that CDT is not locating your MingW or GCC installations.
simple - but unlikely reason - covering bases
There can be many reasons, from the simple - but unlikely at this point:
You don't have mingw installed
You don't have GCC installed
This can be tested easily by starting a shell and running gcc --version.
CDT heuristic not working
To more complicated reasons relating to your installation not being detected because the heuristic in CDT did not work on your machine. To find the correct settings, CDT will do:
Check $MINGW_HOME/bin for existence
Check <Eclipse install location>/mingw/bin for existence
Look for mingw32-gcc.exe or x86_64-w64-mingw32-gcc.exe on the PATH
Check C:\MinGW for existence
If CDT cannot find any of the above, you may lead to the situation you are in.
So, how to fix it!
Option 1
Start Eclipse from within a mingw set up shell. i.e. the one you can successfully run gcc --version from. That way Eclipse will inherit an environment that can launch GCC successfully.
Option 2
Set your environment up so that MINGW_HOME is properly defined. You can do this at the system level or within the build settings in Eclipse CDT. For example, on my machine in the build settings for the project (Right-click on the project, choose Properties, then choose C/C++ -> Environment) I have set:
MINGW_HOME to C:\MinGW
MSYS_HOME to C:\MinGW\msys\1.0
PATH to ${MINGW_HOME}\bin;${MSYS_HOME}\bin;<my normal path>
and this allows Eclipse to launch gcc as part of the build process.
NOTE The above setting were done automatically on my machine because mingw was correctly located by the heuristic.
Here is a screenshot of the build settings if it helps:
Prefix: Under the hood
To try and answer part of your original question about what Prefix is, I provide the below information. It is unlikely to be particularly helpf
Prefix, in GCC parlance, refers to the directory under which all the related GCC files are placed. With different prefixes you can have multiple GCC installed on your machine.
From the GCC FAQ:
It may be desirable to install multiple versions of the compiler on
the same system. This can be done by using different prefix paths at
configure time and a few symlinks.
The concept comes from autotools in general. Autotools is the standard GNU make system (where you do ./configure && make - simplified). The prefix is the command line option to the configure stage (--prefix) to specify where to install the tool to. GCC above uses the --prefix to allow multiple GCCs on your system.
If you really want to know more about this, read the autobook. The section on configuring covers --prefix:
‘--prefix=prefix’
The –prefix option is one of the most frequently
used. If generated ‘Makefile’s choose to observe the argument you pass
with this option, it is possible to entirely relocate the
architecture-independent portion of a package when it is installed.
For example, when installing a package like Emacs, the following
command line will cause the Emacs Lisp files to be installed in
‘/opt/gnu/share’:
$ ./configure --prefix=/opt/gnu
It is important to stress that this behavior is dependent on the generated files making use of this
information. For developers writing these files, Automake simplifies
this process a great deal. Automake is introduced in Introducing GNU
Automake.
Additionally, Mingw takes advantage of all this prefix options. Read more about that on mingw's site. But the short of it is that the main prefix for mingw is /mingw.

Can I use the Intel C++ compiler with biicode?

biicode is a dependency management system for C++. I use the Intel C++ compiler (ICC), rather than gcc. Is it possible to use biicode, but continue to use ICC for building my project and dependencies?
As biicode uses the CMake build system, it should be possible just indicating CMake that you want to use that compiler. Depending on the platform it can be done differently. You can find info about setting different compilers here
E.g. in Linux, it could be enough to define environment variables:
CC=icc
CXX=icc
bii build
You can pass variables and options to cmake project configuration with the command bii configure, exactly as they would be passed to cmake, e.g. the generator:
bii configure -G "Visual Studio 12" -DMY_OPTION="myvalue"
So you could try something like:
bii configure -D CMAKE_CXX_COMPILER=icc
In win with VS, you might need to set the toolset, this can be done with something like this in your CMakeLists.txt:
set(CMAKE_GENERATOR_TOOLSET "Intel C++ Compiler XE 14.0" CACHE STRING "Platform Toolset" FORCE)
Though in general, specific configuration of compilers in the CMakeLists should be avoided and setting the environment via env or variables is preferred.