How to disable link time code generation in CMake - cmake

We are using CMake with the Visual Studio 2015 generator and I am trying to disable link time code generation for libraries and executables under the debug build configuration. It seems that when I modify the linker flags with
SET_TARGET_PROPERTIES(${_PROJNAME} PROPERTIES LINK_FLAGS_DEBUG "${LINK_FLAGS_DEBUG} /LTCG:OFF")
that CMake still generates solutions with /LTCG:INCREMENTAL in the linker additional options but also with /LTGC:OFF appended. Does anyone know a way to turn LTCG off completely for all configurations so I can enable it just for those that we want it enabled for?
cmake version 3.10.0-rc2

If something ends up under "Additional Options" in the generated VS projects, it means CMake didn't recognize the option given (and therefore didn't replace its own default).
See CMake's source cmVS141LinkFlagTable.h:
{ "LinkTimeCodeGeneration", "", "Default", "Default", 0 },
{ "LinkTimeCodeGeneration", "LTCG:incremental", "Use Fast Link Time Code Generation", "UseFastLinkTimeCodeGeneration", 0 },
{ "LinkTimeCodeGeneration", "LTCG", "Use Link Time Code Generation", "UseLinkTimeCodeGeneration", 0 },
{ "LinkTimeCodeGeneration", "LTCG:PGInstrument", "Profile Guided Optimization - Instrument", "PGInstrument", 0 },
{ "LinkTimeCodeGeneration", "LTCG:PGOptimize", "Profile Guided Optimization - Optimization", "PGOptimization", 0 },
{ "LinkTimeCodeGeneration", "LTCG:PGUpdate", "Profile Guided Optimization - Update", "PGUpdate", 0 },
But if I look at CMake's VS 2015 defaults:
CMAKE_EXE_LINKER_FLAGS = /machine:X86
CMAKE_EXE_LINKER_FLAGS_DEBUG = /debug /INCREMENTAL
CMAKE_EXE_LINKER_FLAGS_RELEASE = /INCREMENTAL:NO
There is no /LTCG:INCREMENTAL in the defaults. So I think what you are actually looking for/what would help you is:
set_property(
TARGET ${_PROJNAME}
APPEND_STRING
PROPERTY
LINK_FLAGS_DEBUG " /INCREMENTAL:NO"
)

You could manually modify CMake cache variables CMAKE_EXE_LINKER_FLAGS_DEBUG, CMAKE_MODULE_LINKER_FLAGS_DEBUG, CMAKE_SHARED_LINKER_FLAGS_DEBUG and CMAKE_STATIC_LINKER_FLAGS_DEBUG as wished.
You could remove the /INCREMENTAL flag from these variables.

Related

How to set working directory in CMake Visual Studio 2022?

I have a problem with setting the working directory with CMake (Visual Studio 2022).
I'm currently working on a project (some OpenGL learning stuff) and decided to switch from typical VS solution-project to CMake project. I need to load some files (.obj, shaders) from Resources folder (LearnOpenGL/Resources) but I see that paths in c++ code are relative to LearnOpenGL/out/build/x64-Debug/.
I've already tried :
setting property VS_DEBUGGER_WORKING_DIRECTORY like (also without trailing slash):
set_property(TARGET LearnOpenGL PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/")
adding "currentDir" or "cwd" to CMakeSettings.json like:
"currentDir": "${projectDir}"
"cwd": "${projectDir}"
but there is no effect of any of those changes. Does anyone have some ideas what else can I do? Or maybe I'm doing here something wrong?
You can add currentDir property to your launch.vs.json which will typically be in ${workspaceRoot}/.vs directory.
To access it from Visual Studio 2022 CMake project you can follow these steps:
In the solution explorer click on Switch between solutions and available views button:
Then click on CMake Targets View
Now right click on your project and press Add Debug Configuration in context menu
This will open launch.vs.json file where you can edit currentDir property, for example - my project 02_texture.exe should start in root directory so my launch config looks like this:
{
"version": "0.2.1",
"defaults": {},
"configurations": [
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "",
"name": "CMakeLists.txt"
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "02_texture.exe (02_texture\\02_texture.exe)",
"name": "02_texture.exe (02_texture\\02_texture.exe)",
"currentDir": "${workspaceRoot}"
}
]
}

Using CMake compile flags in preset for non-external projects only

I am adding a few external projects to my application. For instance, gtest.
In my CMake preset I set the following...
{
"version": 4,
"cmakeMinimumRequired": {
"major": 3,
"minor": 23,
"patch": 0
},
"configurePresets": [
{
"name": "debug",
"displayName": "debug",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_CXX_FLAGS": "/W4 /Wall /EHsc",
"CMAKE_CXX_STANDARD": "20",
"CMAKE_CXX_STANDARD_REQUIRED": "YES",
"CMAKE_CXX_EXTENSIONS": "OFF"
}
}
]
}
When I build with the above preset, I get a bunch of warnings from building gtest. I only would like to see the warnings coming from my internal build, not external projects.
In my root CMakeLists.txt I have the following...
cmake_minimum_required(VERSION 3.23.0)
project(ProjectName LANGUAGES C CXX CUDA)
include(CTest)
add_subdirectory(external) # This has a bunch of external dependencies.
add_subdirectory(src) # This builds a normal executable.
add_subdirectory(tests) # This has various unit tests.
Is there a way for me to make sure the flags are only used for my personal project, and nothing external?
I have looked into "https://cmake.org/cmake/help/v3.23/manual/cmake-presets.7.html" but nothing stood out to me.
Thank you
If you want to localize your settings you should not use globals. Use target_compile_options and other target_* commands instead of setting CMAKE_CXX_* global (cache) variables in your preset.
Alternatively, you can choose not to build external projects as part of your local project build. With that organization you wouldn't have the problem in the first place.

Setting up platform-specific default tasks in VS Code

Broader Question:
This post originally asked about how to specify a platform-specific problem matcher, but it seems that the more important question to be answered is:
How do you set up platform-specific properties for tasks when those properties are not recognized in the "windows" or "linux" sections?
Even if I break this task into two tasks, it seems that only one of them can be set as the default build task for both platforms.
Before anyone asks, this problem stems from the need to commit my tasks.json file to the repository so that the other developers are able to build the project on any platform using the "Run Build Task..." command in VS Code. I realize they could always change the default task after checking out the code.
Original Question:
I have a task in VSCode that runs a shell/batch script for building my C++ (CMake) application. The task makes use of the "windows" and "linux" keys for platform-specific commands.
{
"label": "Build x64",
"type": "shell",
"windows": { "command": "${workspaceRoot}/Build-Win-x64.bat" },
"linux": { "command": "${workspaceRoot}/Build-Linux-x64.sh" },
"group": { "kind": "build", "isDefault": true }
}
The Windows script builds with the MSVC compiler which requires putting "problemMatcher": "$msCompile" in the task so that VSCode can parse the compiler output.
However the Linux script uses GCC which requires "problemMatcher": "$gcc".
These values seem to be mutually exclusive and VSCode does not allow them inside the platform-specific properties.
Is there any way to set up a default build task with different problem matchers for each platform?
I've thought about using an environment variable like this "problemMatcher": "${env:VSCODE_CPP_MATCHER}" but this would be annoying to set up for every workstation that works with this project.
It turns out that you can use an array of problem matchers!
{
"label": "Build",
"windows": { "command": "${workspaceFolder}/Build-Win-x64.bat" },
"linux": { "command": "${workspaceFolder}/Build-Linux-x64.sh" },
"problemMatcher": ["$msCompile", "$gcc"]
}
Since this solution lets me use the same task for Windows and Linux, I don't need to define separate default build tasks for each platform.
Just out of curiousity, is it possible to set up a different default build task for each platform?

Vue Dev Tools - does not working "Open in Editor" button. How to fix this?

I am trying to setup this feature from tutorial:
https://github.com/vuejs/vue-devtools/blob/master/docs/open-in-editor.md
but got an error
"C:\Users\User\AppData\Local\Programs\Microsoft" не является внутренней или внешней, исполняемой программой или пакетным файлом.
Could not open LeadsEdit.vue in the editor.
The editor process exited with an error: (code 1).
To specify an editor, sepcify the EDITOR env variable or add "editor" field to your Vue project config.
in my vue.config.js (project based on vue cli 3.0)
const openInEditor = require('launch-editor-middleware');
module.exports = {
configureWebpack: {
devtool: 'source-map',
},
devServer: {
before(app) {
app.use('/__open-in-editor', openInEditor('code'))
}
}
}
UPD. Without this code the problem still remain.
UPD2.
I am trying to set EDITOR variable in .env file
VUE_APP_EDITOR=/c/Users/User/AppData/Local/Programs/Microsoft VS Code/Code.exe
Or with vue.config.js
const openInEditor = require('launch-editor-middleware');
module.exports = {
configureWebpack: {
devtool: 'source-map',
},
devServer: {
before(app) {
app.use('/__open-in-editor', openInEditor('/c/Users/User/AppData/Local/Programs/Microsoft VS Code/Code.exe'))
}
}
}
But the problem still remains
What may cause this problem?
How can I fix this error?
It seems like dev tools is trying to open the editor executable C:\Users\User\AppData\Local\Programs\Microsoft, which is most likely wrong. The default install location on Windows 10 is (to the best of my knowledge) C:\Users\User\AppData\Local\Programs\Microsoft VS Code\Code.exe.
launch-editor tries to find the editor from the currently running processes and falls back to the environment variables EDITOR and VISUAL (see https://github.com/yyx990803/launch-editor#why), so you can probably set the EDITOR env var to the correct path.
Probably, there are quotes missing around the editor config so it gets cut off at the first space. I don't really know where the path comes from, either you configured it via environment variables or in your vue project config.
Based on the information in your updated question, you could try this:
I don't know where the variable name VUE_APP_EDITOR comes from, but I guess it should be EDITOR. Change it to EDITOR and see what happens
The path you are using looks wrong (i.e. not like a windows path). Try c:/Users/User/AppData/Local/Programs/Microsoft VS Code/Code.exe instead.
E.g.:
app.use('/__open-in-editor', openInEditor('c:/Users/User/AppData/Local/Programs/Microsoft VS Code/Code.exe'))
You can test whether the path is correct by starting a cmd shell and entering the path. If it is correct, VS Code should open. If not, it will tell you the path was not found.
Also have a look at this, there is some more on how to integrate vue devtools & VS Code: https://gist.github.com/moreta/d3989686b6a1f2416b5802cac8df16b4

Durandal.js optimizer not working (empty main-built.js)

I'm trying to get Durandal.js optimizer working on my test project, but it seems to generate nothing to main-built.js. I use the following command from node.js command prompt, in durandal/amd folder:
optimizer.exe --verbose true
Result is
Using default base configuration.
Configuring for deploy with almond (custom).
{
"name": "durandal/amd/almond-custom",
"inlineText": true,
"stubModules": [
"durandal/amd/text"
],
"paths": {
"text": "durandal/amd/text"
},
"baseUrl": "C:\\Users\\Tommi Gustafsson\\Documents\\Visual Studio 2012\\Projects\\DurandalTests\\DurandalTest1\\TestApp",
"mainConfigFile": "C:\\Users\\Tommi Gustafsson\\Documents\\Visual Studio 2012\\Projects\\DurandalTests\\DurandalTest1\\TestApp\\main.js",
"include": [
"main-built",
"main",
"bindings/tinymce-binding",
"durandal/app",
"durandal/composition",
"durandal/events",
"durandal/http",
"text!durandal/messageBox.html",
"durandal/messageBox",
"durandal/modalDialog",
"durandal/system",
"durandal/viewEngine",
"durandal/viewLocator",
"durandal/viewModel",
"durandal/viewModelBinder",
"durandal/widget",
"durandal/plugins/router",
"durandal/transitions/entrance",
"raphael-amd/eve.0.3.4",
"raphael-amd/raphael.2.1.0.amd",
"raphael-amd/raphael.2.1.0.core",
"raphael-amd/raphael.2.1.0.svg",
"raphael-amd/raphael.2.1.0.vml",
"viewmodels/flickr",
"viewmodels/modal1",
"viewmodels/myPage",
"viewmodels/shell",
"viewmodels/welcome",
"text!views/detail.html",
"text!views/flickr.html",
"text!views/modal1.html",
"text!views/myPage.html",
"text!views/shell.html",
"text!views/welcome.html"
],
"exclude": [],
"keepBuildDir": true,
"optimize": "uglify2",
"out": "C:\\Users\\Tommi Gustafsson\\Documents\\Visual Studio 2012\\Projects\\DurandalTests\\DurandalTest1\\TestApp\\main-built.js",
"pragmas": {
"build": true
},
"wrap": true,
"insertRequire": [
"main"
]
}
Deleting old output file.
Tracing dependencies for: durandal/amd/almond-custom
Then, when I check main-built.js, it is empty. Can anyone help me what is the problem? I have several AMD modules in the test project, including Raphael.js AMD modules.
My requirejs configuration looks like this:
requirejs.config({
paths: {
'text': 'durandal/amd/text',
'eve': './raphael-amd/eve.0.3.4',
'raphael.core': './raphael-amd/raphael.2.1.0.core',
'raphael.svg': './raphael-amd/raphael.2.1.0.svg',
'raphael.vml': './raphael-amd/raphael.2.1.0.vml',
'raphael': './raphael-amd/raphael.2.1.0.amd',
'tinymce': "../Scripts/tinymce/jquery.tinymce.min"
}
});
In the same amd folder, where optimizer is stored, try running node r.js -o app.build.js. I've seen r.js sometimes choke about some dependencies, which resolves without problem when loading via require.js. For whatever reason the error messages won't show up when using optimizer --verbose. Typically the error message provides enough information to see where this occurs and if you've to update require.contig.paths or a specific define dependency.