CMake COMPILE_DEFINITIONS triggering incorrect number of arguments - qt

I'm having problem understanding how to correctly set the COMPILE_DEFINITIONS target properti in CMake.
my target is add_library(modelutilities STATIC ${modelutilities_SRCS})
I if use
set(modelutilities_COMPILE_DEFINE ${modelutilities_COMPILE_DEFINE} ${Qt5Widgets_COMPILE_DEFINITIONS})
set_target_properties(modelutilities PROPERTIES
VERSION "0.0.1"
SOVERSION 0
EXPORT_NAME "ModelUtilities"
ARCHIVE_OUTPUT_DIRECTORY "${modelutilities_PlatformDir}/lib"
LIBRARY_OUTPUT_DIRECTORY "${modelutilities_PlatformDir}/lib"
RUNTIME_OUTPUT_DIRECTORY "${modelutilities_PlatformDir}/bin"
COMPILE_DEFINITIONS ${modelutilities_COMPILE_DEFINE}
)
everything works fine, but if I add another line between them with set(modelutilities_COMPILE_DEFINE ${modelutilities_COMPILE_DEFINE} MODELUTILITIES_LIB) it stops working complaining that set_target_properties was called with the wrong number of arguments.
Anyone can spot what I'm doing wrong?
P.S.
I already tried using doublequotes: set(modelutilities_COMPILE_DEFINE ${modelutilities_COMPILE_DEFINE} "MODELUTILITIES_LIB"). It did not change anything
P.P.S.
If I message(STATUS ${modelutilities_COMPILE_DEFINE}) QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB in the first case and QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;MODELUTILITIES_LIB in the second

With newer version of CMake, what is being preached is the idea of targets. So, for example, instead of include_directories() it's now preferred to use target_include_directories().
That being the case I think you'd be better served using the preferred target_compile_definitions() to set compile definitions for your utilities library.
One advantage you get is that your can scope your compile definitions using the PUBLIC or PRIVATE keywords.

Related

Why Juila module have to be prefixed with dot?

Why module using .A has to be prefixed with dot? It doesn't work if you omit the dot.
File ./A.jl
module A
export sayHi
function sayHi()
println("hi")
end
end
File ./Main.jl
include("./A.jl")
using .A # <= Why it has to be prefixed with dot?
sayHi()
Running, start REPL and type
include("./Main.jl")
Part 2
And if you move file A.jl to different location, like ../some-dir/A.jl it has to be prefixed to two dots using ..A. Why?
Because you define module A inside your current module. The dot means "look inside the current module for this". https://docs.julialang.org/en/v1/manual/modules/#Relative-and-absolute-module-paths-1
After digging it deeper - it seems like the answer is - don't use modules.
The documentation is wrong, it says
When in reality, the module usage is heavily tied to the location of files, it could be using Foo, using .Foo, using ..Foo or using Main.Foo - depending on the location of the Foo module relative to the file that imports it. In my personal opinion - something is very wrong with that design.
No support in the VSCode Editor, it doesn't understand using ..Foo. There are other ways to use modules, including altering startup.jl or JULIA_LOAD_PATHS - none of it works either. I assume nobody noticing these problems because nobody actually using modules.
Top answer on YCombinator - gives the same answer - the best way to use modules in Julia - is to not use it at all https://news.ycombinator.com/item?id=19232824

Spec not allow body (remove in gpr file) without touching source files

I got the following error wich is common with generated sources:
spec of this package does not allow a body
I would like to know if it exist a rule to put in the gpr file to ignore this error.
Like a ignore flag.
As I mentionned this files are generated so i have no right on them (not alowed to suppress them neither rewrite them).
More over it would be nice to have a rule that work for every generation.
If you were to compile
package Guillaume is
end Guillaume;
package body Guillaume is
end Guillaume;
in Ada 1983 mode, you would get e.g.
gnatmake -gnat83 guillaume.ads
gcc -c -gnat83 guillaume.ads
guillaume.ada:1:09: warning: package "Guillaume" does not require a body
guillaume.ada:1:09: warning: body in file "guillaume.adb" will be ignored
Having a body that isn’t required by the spec was made illegal with Ada 95 (it would be possible to change a body and for the compilation process not to notice that it needed to be recompiled, leading to confusion). If your code generator was designed to produce Ada 83, then I guess you may have to face compiling in Ada 83 mode - but GNAT doesn’t, as far as I know, guarantee to be 100% compatible, particularly as far as the run time system is concerned.
Are the offending package bodies all actually empty? If so, you might be able to list them and use the Excluded_Source_List_File attribute in your project. If not, you are in trouble, because there’s no way (without changing package sources) to get the code in them to execute.
(Later): actually, Excluded_Source_List_File doesn’t help; it stops gprbuild looking at the file, but not the compiler; and it’s the compiler that rejects the body. Sorry. But if you could make such a list you could use it to delete the bad bodies.
You can exclude the body from the list of source files:
for Excluded_Source_Files use ("my_body.adb");

make does not realize that a relative path name dependency is the same as an absolute pathname target

The following is a simplified makefile for a problem I'm having:
all: /tmp/makey/../filey
#echo All done
/tmp/filey:
#echo Filey
When I run make it says:
make-3.79.1-p7: * No rule to make target /tmp/makey/../filey', needed byall'. Stop.
Clearly it does not realize that /tmp/makey/../filey is the same as /tmp/filey. Any ideas how I can make this work?
Thanks
Ciao
-- Murali
Newer versions of GNU make have $(abspath ...) and $(realpath ...) functions you can apply to your prerequisites and targets to resolve the paths to the same string. If you've constructed these names yourself (for example, $(PREFIX)/../filey) then you can use $(dir $(PREFIX))filey instead.
Other than that, there's no way to solve this problem. Make uses string matching on targets and if the strings are not identical, they don't match (there's a special case to ignore the simple prefix ./) Even if make understood this distinction (by applying abspath itself to each target name, maybe) it would still not help in the face of symbolic links for example.
The only "real" answer would be for make to understand something about the underlying file system (device IDs and inodes for example) that let you talk about files without referring to their pathname. However, in a portable program like make doing this is problematic.

GNAT Programming Suite - source file not found

Ada is still new to me, so I am trying to find my way around the GPS IDE. I asked another question earlier, but I think this problem has precedence over that one, and may be at the root of my trouble.
When I compile, I am getting a long list of *warning: source file ... not found"
In my .gpr file, I have listed all of the spec and body source files and use the following naming scheme:
package Naming is
for Casing use "mixedcase";
for Dot_Replacement use ".";
for Spec_Suffix ("ada") use "_s.ada";
for Body_Suffix ("ada") use "_b.ada";
end Naming;
What is odd it the error messages all look either like this:
warning: source file "xxx_b.adb" not found
or this
warning: source file "xxx.adb" not found
Note that neither of these (xxxb.adb or xxx.adb) conform to the file specs, which should end with .ada.
Can someone explain what is going on here?
I'm 99% sure that the problem is one of the ones I mentioned in answer to your other question: GNAT does not normally support more than one compilation unit in a file. I got exactly the behaviour you describe with GPS and these files:
james_s.ada:
with Jane;
package James is
end James;
jim_s.ada:
package Jim is
end Jim;
package Jane is
end Jane;
The error message on compiling james_s.ada says it can't find Jane_s.ada, but when I ask GPS to go to the declaration of Jane it takes me to the "correct" line in jim_s.ada.
You could use gnatchop to split jim_s.ada, but it doesn't understand project files or naming conventions; you probably want to keep the existing names for the code that works, so you'd rename gnatchop's output as required.
However! to my great surprise, it turns out that GNAT does support having more than one compilation unit in a file, provided package Naming in the project file tells it about each unit in the file:
package Naming is
for Casing use "mixedcase";
for Dot_Replacement use ".";
for Spec_Suffix ("ada") use "_s.ada";
for Body_Suffix ("ada") use "_b.ada";
for Spec ("Jim") use "jim_s.ada" at 1;
for Spec ("Jane") use "jim_s.ada" at 2;
end Naming;
It's up to you whether to do this or to bite the bullet and use gnatchop, either on the multi-unit files or on the whole source tree.
First off, this isn't an Ada problem, its a Gnat problem. Other Ada compilers have no problem with the file names you are using.
However, Gnat is rather unique in that it expects there to be only one program unit (package body, package spec, stand-alone routine, etc) per source file. This is because it is also rather unique in that it expects to be able to find the source code for any program unit just by knowing that unit's Ada intentifier. Most other Ada compilers maintain some kind of library file that maps file names to program units, and you have to register all your files into it. (Whereas your typcial C compiler just leaves the problem of finding files for all your code up to the user entirely).
Generally the easiest thing to do with Gnat, the way that will cause you the least trouble, is to just use its default file naming convention (and of course don't put multiple program units in a single file.
If you already have some existing Ada code (perhaps developed for another compiler), the easiest way to import it into Gnat is typically to run the gnatchop tool on it all. So that's what I'd suggest you try.
From GPRbuild User's Guide:
Strings are used for values of attributes or as indexes for these attributes. They are in general case sensitive, except when noted otherwise [...]
Based on this, I believe you have to use "Ada" instead of "ada" as index for Spec_Suffix and Body_Suffix. I currently do not have access to the tools for testing this, so I suggest to just try it out.

Generating multi-mode executables with a single CMakeLists.txt

Is there a way to create separate executables within one CMakeLists.txt file for the same classes, but for a different intention? This is somewhat like the DEBUG/RELEASE switch, but I need to do a decision at source code level.
Pseudo-CMakeLists.txt:
SET_INTENTION(app1 1)
ADD_EXECUTABLE(app1 main.cxx)
SET_INTENTION(app2 2)
ADD_EXECUTABLE(app2 main.cxx)
Pseudo-Code main.cxx:
if (intention == 1)
//do something different to intention == 2
I tried ADD_DEFINITIONS as preprocessor definitions and #ifdef in source, but CMake seems to interpret the whole file and got all definitions, no matter at what position the definition was added. Splitting the ADD_EXECUTABLES() into two CMakeLists.txt (in subfolders) is not really straight forward and leads to problems when using QT4_WRAP_CPP and QT4_WRAP_UI. I appreciate any ideas / workarounds.
The COMPILE_DEFINTIONS property looks promising:
add_executable(app1 main1.cxx)
get_target_property(APP1_COMPILE_DEFS app1 COMPILE_DEFINITIONS)
set_target_property(app1 PROPERTIES COMPILE_DEFINITIONS "${APP1_COMPILE_DEFS};INTENTION=1")
add_executable(app2 main2.cxx)
get_target_property(APP2_COMPILE_DEFS app2 COMPILE_DEFINITIONS)
set_target_property(app2 PROPERTIES COMPILE_DEFINITIONS "${APP2_COMPILE_DEFS};INTENTION=2")
Then use preprocessor #if INTENTION=1 and so forth in your source files. If you're not using a recent CMake, you may need to mess with the COMPILE_FLAGS property instead.

Resources