how to create global nanoc variable between preprocessor and rule - nanoc

I create variable #foo in preprocessor block. It is global for the time of preprocessing, i.e. different methods can access it. However, in compilation time, i.e. in Rules, this variable is not available.
Currently, I use #config map to store such variables. How to create global variable that will be shared without using the #config map?

Related

Any way to redefine global variable in .gitlab-ci.yml?

I've changed the value of the variable defined in my .gitlab-ci.yml, but I've noticed, that the old value is still used.
After a few retries I've checked the global configuration to find out, that the variable with the same name is defined in the global CI settings, and my pipeline is not taking the 'old' value defined in .gitlab-ci.yml, but that defined in the global scope.
Is there any way to override the globally defined variables, or at least get warned when the global value gets the precedence?
Some commands are very strict about what variables they use, and if someone defined the global defaults, that need to be changed in my case, I have a little problem here.

How do a generate a JavaScript function scoped variable with Blockly?

I have a function block in my Blockly workspace, but I can't seem to find a way to add a variable that is scoped to a function. Adding a variable to the workspace generates a variable defined at the top of my generated code.
Is there a way with the pre-built blocks to create a variable within a function block?
Unfortunately, not really; all of the variables in Blockly are global. One thing you can do is have the function block in some way know which variables it's using and then redefine it with 'let' inside the function such that it won't be modified outside of the function, but variable selectors will still be able to select the variable regardless of location.

How can I append to a construction variable in a Program() call?

I have a custom environment set up for my tests:
test_env = env.Clone()
test_env.Append(LIBS=['boost_unit_test_framework'])
But for one of my tests, I want to link against an additional library:
test_env.Program('foo_tests',
source='foo/tests.cpp',
LIBS=['extralib'],
LIBPATH=['.'])
Sadly this overrides the LIBS from the environment, when I'd like it to just add to it. Is there a better (i.e. more canonical) way to do this than LIBS=test_env['LIBS'] + ['extralib']?
Specifying a new value for an environment variable in a Builder call (like Program) is always interpreted as an "override". So there is no way around compiling the full replacement value, as you did in your example above.
The other option would be to Clone the environment "test_env" again, and then use Append to add the "extralib" to LIBS...
It's possible to do it like this:
test_env.Program('foo_tests',
source='foo/tests.cpp',
LIBS=['$LIBS', 'extralib'],
LIBPATH=['$LIBPATH', '.'])
SCons is clever enough to properly expand the variable into a list there.

cmake, lost in the concept of global variables (and PARENT_SCOPE or add_subdirectory alternatives)

I have a cmake project in which I have some modules and I'm using Find-*.cmake for including the shared modules in the application.
For not taking in account every module that I add, I have defined a kind of global LIB variables tor the linker:
# inside a Find-*.cmake or in the CMakeLists.txt of the modules:
set(LIB ${LIB} ...)
so in one of the final applications that uses some modules I can just do:
target_link_libraries(${APP_NAME} ${LIB})
Then, I'd like to have the compiled modules in the /project_path/modules/foo/build so that if a module is really big to compile it can be compiled once for all the application that use it. The way I'm achieving this is to load the CMakeLists.txt of the module from the Find-*.cmake in this way:
# Inside FindFoo.cmake, for loading /project_path/modules/foo/CMakeLists.txt
# and compile it in /project_path/modules/foo/build
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME}
${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME}/build
)
include_directories(${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME}/include)
But it happened sometimes that some module require another modules so that the add_subdirectory creates new scopes and can correctly load LIB but cannot write it (when I use set it is in the deeper scope and not changes the upper scope). For bypass this I have to add PARENT_SCOPE in the set).. So I have tried to add it in some module that I think could be nested and hidden in some dependencies but compiling all the application I suddenly faced with:
CMake Warning (dev) at /path_to_repo/cmake/FindFooX.cmake:6 (set):
Cannot set "LIB": current scope has no parent.
Call Stack (most recent call first):
CMakeLists.txt:14 (find_package)
This warning is for project developers. Use -Wno-dev to suppress it.
I am afraid that this can change from app to app in respect to which module I need or in respect of the dependecies tree in the modules itself so I'm looking for a cleaner solution.
You can 'simulate' GLOBAL variable behavior, by using properties with GLOBAL scope :
SET_PROPERTY(GLOBAL PROPERTY MyGlobalProperty "MyGlobalPropertyValue")
Then you can extract your global property by using
GET_PROPERTY(MyLocalVariable GLOBAL PROPERTY MyGlobalProperty)
Then, MyLocalVariable contains "MyGlobalPropertyValue".
Because PARENT_SCOPE extends variable definitions to the only parent directory (and not to its parents), there are cases it's not enough, for example if you have a deep source tree...
All variables in CMake are local by default. While you can use the PARENT_SCOPE parameter to increase the scope of a local variable by one layer, that mostly makes sense for return values of functions.
For find scripts on the other hand you usually want the behavior of a global variable: Once the find script is called by anyone, you want the results to be available everywhere. In particular, a second call to the same find script should just reuse the results of the first call.
In CMake this is achieved by storing variables to the cache. The various find_* calls already do this automatically, so you should prefer using those where applicable. For any additional custom variables, set offers the capability to store to the cache as well:
set(MY_GLOBAL_VARIABLE "Some value" CACHE STRING "Description")
Note that local variables can hide cached variables of the same name in their scope.

Why are nonstatic global variables defined in shared objects referenced using GOT?

I mean nonstatic global variables that are defined in the module, not externally.
Why does it have to be referenced through GOT? Why no use relative address?(since the distance between the global variable in the .data section and the reference in the .text section is a constant, it's also position-independent)
Since your variable isn't static, on ELF it can be interposed (think of LD_PRELOAD).
I also have the same confusion.
If there is one global variable with same name defined in both two DSOs and they are dynamically linked into one executable, will both libraries access the same copy of the variable?
And which library(library's data section) the variable locates depends on the order of libraries loading?

Resources