How to tell where a variable is coming from? - cmake

I have a directory with CMakeLists.txt. And it invokes a CMake module module1.cmake file located elsewhere.
module1.cmake will reference a variable named XXX, which may come from:
the environment variable %XXX%.
the command line through cmake -D XXX=
XXX defined in the invoking directory's CMakeLists.txt through set().
and the CACHE entry in the previously configured build folder
Then module1.cmake will store the variable XXX into the CACHE.
In the module1.cmake file, I need to tell where XXX is from because I need to treat them differently.
For 1, I can check the value of $ENV{XXX}.
For 4, I was thinking about using get_property(cached_XXX CACHE XXX PROPERTY VALUE) and check the value of cached_XXX. But it turns out the -D XXX= option always update the CACHE entry. So I cannot tell if the cached_XXX value is from an old CACHE or from the current -D option.
So after all, how can I tell between 2, 3 and 4?

Related

CMake replaces part of absolute path to command with relative "../../" in add_custom_target

I'm trying to add a custom target to my cmake setup. It's needed as I want to execute particular tool with a set of arguments. The executable itself is prebuild and located in the repo which I want to build (so there is explicit .exe in repo, it's not builded).
I used following cmake command:
add_custom_target(some_target ALL DEPENDS ${INPUT_FILES} COMMAND <path_to_repository>/<path_within_repository>/my_tool.exe "arguments")
This is crux of a problem:
<path_to_repository>/<path_within_repository>/my_tool.exe
The path to the executable is build as a absolute path which uses some dynamic and static parts (<path_to_repository> is obviously dynamic and deducted before the "add_custom_target". <path_within_repository> is static one, hardcoded within cmake.)
So for example we have:
C:/user/repos/source/MY_REPO/PROJECT/Sources/SpecialTool/bin/my_tool.exe
<path_to_repo ------------->/<path_within_repository ------->
Problem is when I start to execute the cmake and build. From the logs I can see that because of some reason the part of <path_to_repository> ALWAYS gets replaced by "../../" (although I use message() to print the full <path_to_repository>/<path_within_repository> and it is correct). So when it comes to executing the command I get a following in make logs:
../../Sources/SpecialTool/bin/my_tool.exe
which fails with a rather simple error message of
'..' is not recognized as an internal or external command,
operable program or batch file.
as it tries to build it on Windows, so obviously the relative path with "/" instead of "\" doesn't work (Source/SpecialTool/bin/my_tool.exe would work, but apparently you cannot use slashes and relative path on Windows).
So there are 2 problems:
Why the part of absolute path gets replaced with a relative one (so instead of <path_to_repo> make uses "../../" )?
How to enforce the use of "\" instead of "/" (so that the relative ..\..\Sources\...\my_tool.exe path works) ?
I've already tried putting backslash in the path ( so
C:\\user\\repos\\source\\MY_REPO\\PROJECT\\Sources\\SpecialTool\\bin\\my_tool.exe), use quotes etc. and it seems nothing have had worked. I've also tried to use add_custom_command and then use it in add_custom_target, but that gave me exactly the same behavior as a direct call to command in add_custom_target.
The only instance when this problem does not occur is when I manually put the "my_tool.exe" somewhere above the repository itself in folder hierarchy (so C:/user/repos/source/my_tool.exe or C:/my_tool.exe, naturally the path then doesn't contain full path to builded repository itself). It is also not possible for me to actually use this when writing the cmake for this project.

Create repository in non-empty remote folder

It's been 14 years since I last worked with svn and appearently I have forgotten everything...
I have an existing web-project, consisting of a bunch of php, html, js and other files in a directory tree on a V-Server. Now I want to take these folders under version control and create a copy on my local machine using svn. So I installed subversion according to these instructions: https://www.linuxcloudvps.com/blog/how-to-install-svn-server-on-debian-9/
Using the already-present apache2.
But now I kinda hit a roadblock. If I try svnadmin create on the existing folder, it tells me that is is not empty and does nothing really. All the questions and answers I find here and elsewhere are either
a) focussing on an already existing folder on the local machine
b) assuming more prior knowledge than I have right now aka I don't understand them.
Is there a step-by-step guide for dummies anywhere on how to do this? Or can anyone tell me in laymans terms how to do this?
I can't believe this case never comes up or that it is really very complicated.
At the risk of failing to understand your exact needs, I think you can proceed as follows. I'll use this terms:
Code: it's the unversioned directory at V-Server where you currently have the bunch of php, html, js and other files
Repository: it's the first "special" directory you need to create in order to store your Subversion history and potentially share it with others. There must be one and there can only be one.
Working copy: it's the second "special" directory you need to create in order to work with your php, html, js... files once they are versioned and it'll be linked to a given path and revision of your repository. At a given time there can be zero, one or many of them.
Your code can become a working copy or not, that's up to you, but it can never become a repository:
$ svnadmin create /path/to/code
svnadmin: E200011: Repository creation failed
svnadmin: E200011: Could not create top-level directory
svnadmin: E200011: '/path/to/code' exists and is non-empty
Your repository requires an empty folder but it can be located anywhere you like, as long as you have access to it from the machine you're going to use in your daily work. Access means it's located in your PC (thus you use the file: protocol) or it's reachable through a server you've installed and configured (svn:, http: or https:).
$ svnadmin create /path/to/repo
$ 😎
Your working copies can be created wherever you need to work with your IDE. It can be an empty directory (the usual scenario) or a non-empty one. The checkout command retrieves your files from the repo and puts them in the working copy so, at a later stage, you're able to run a commit command to submit your new and changed files to the repository. As you can figure out it isn't a good idea to create a working copy in random directories because incoming files will mix with existing files. There's however a special situation when it can make sense: when the repository location is new and is still empty. In that case you can choose between two approaches:
If you want code to become a working copy, you can check out right into in and then make an initial commit to upload all files:
$ svn checkout file://path/to/repo /path/to/code
Checked out revision 0.
$ svn add /path/to/code --force
A code/index.php
$ svn commit /path/to/code -m "Import existing codebase"
$ Adding /path/to/code/index.php
$ Transmitting file data .done
$ Committing transaction...
$ Committed revision 1.
If you don't care about code once it's stored in the repository or you want your working copy elsewhere, you can import your files from code and create a working copy in a fresh directory:
$ svn import /path/to/code file://path/to/repo -m "Import existing codebase"
Adding code/index.php
Committing transaction...
Committed revision 1.
$ svn checkout file://path/to/repo fresh
A fresh/index.php
Checked out revision 1.

What is the difference between mongooseim.cfg at 2 different places

I am using Mongooseim 3.2.0 and after compiling it from the source code, I can see the mongooseim.cfg at:
1. /MongooseIM/_build/prod/rel/mongooseim/etc/mongooseim.cfg
I can also see that in the docs here that there is another mongooseim.cfg at root level -
2. /MoongoosIM/rel/files/mongooseim.cfg
What is the difference between the two? My guess is path 1 file is copied to the path[2] after compiling the project.
Path 1 (/MongooseIM/_build/prod/rel/mongooseim/etc/mongooseim.cfg) is the actual config file of MongooseIM once it's built. You can tell that by MongooseIM/_build in the path - the _build directory doesn't exist in a fresh clone of the repository. To give you more context, /MongooseIM/_build/prod/rel/mongooseim is a self-contained Erlang release of MongooseIM. Change this file if you want to modify the config of this particular MongooseIM build - the changes will be lost after you rebuild.
Path 2 (/MoongoosIM/rel/files/mongooseim.cfg) is cloned as part of the repository - it's a config template. The specific values are defined in rel/*vars.config files and are substituted for the variables in the template file at build time depending on the Rebar3 profile in use (see rebar.config for profiles). Change this file if you want your changes to remain after consecutive rebuilds of the project.
To cut the long story short, when you run make rel the files /MoongoosIM/rel/files/mongooseim.cfg and /MoongoosIM/rel/vars.config are used to create /MongooseIM/_build/prod/rel/mongooseim/etc/mongooseim.cfg.

How to modify files in post-build script depending on a menuconfig flag?

I need to find a way to modify/edit a given file after Buildroot compilation and right before the creation of the rootfs depending on a menuconfig flag selection. I could find in the Buildroot documentation that it is possible to do that by using post-build scripts.
My problem is that I would do the script action only if I selected something in menuconfig, for example:
(x) Enable my_login_system;
If I select my_login_system, then I need to change the nsswitch.conf file according:
passwd: my_login files
If I don't select in menuconfig the "my_login_system", then the nsswitch.conf should be:
passwd: files my_login
So, my main question is how to know if the "my_login_system" was selected or not in the post-build script.
When a post-build scripts is executed, it can access the BR2_CONFIG environment variable, which holds the path to the Buildroot .config file. Your script can parse that file and act accordingly.
Thus you could have a condition like:
if grep -q ^BR2_MY_LOGIN_SYSTEM=y ${BR2_CONFIG}
then
# do some tweaks
else
# do other tweaks
fi
Alternatively, you could use the BR2_ROOTFS_POST_SCRIPT_ARGS configuration variable to pass arbitrary command line parameters (as opposed to environment variables) to the post-build scripts.
Both possibilities are documented in the Buildroot manual, at section Customizing the generated target filesystem.

How do I configure Mercurial to use environment variables in mercurial.ini

How can I modify the mercurial.ini file to include an environment variable such as %userprofile%.
Specific situation:
I am learning to use Mercurial. I have modified the [ui] section of Mercurial.ini (in my home path) to include:
ignore = c:\users\user\.hgignore
Where user is my username literal. The .hgignore file includes filename filters that are used to ignore files during commit. How can I alter it from being the a literal user to an environment variable $user?
It won't interpolate environment variables in the hgrc, but I do believe that tilda expands to your home/profile directory correctly even on windows.
So:
ignore = ~/.hgignore
should work on windows and elsewhere (even the slashes get spun the wrong way automatically for you).
For other variables you'd need to get a little tricker and write a batch/cmd file that does the interpolation in advance and then hands the result off to mercurial for processing.
The mercurial.ini parses the environment variables just fine.
From my mercurial.ini:
[ui]
ignore = %USERPROFILE%/.hgignore
Works like a charm. Windows 7 Ultimate x64, Mercurial 1.5 (binary installation). The hgignore file is honored both my the command line hg.exe, and tortoiseHG.