Cannot get CMake to handle Fortran-90 modules properly - cmake

I've had a miserable afternoon trying to add a Fortran-90 module to a large multilanguage library set (mostly C++) built with CMake, and am at the point where I am clearly going in circles. There is an amazing dearth of information online that might help me with this, and the CMake documentation is as inscrutable as always.
The library set is too large to boil down properly (so I've been unable to get a good small reproducer) but the essence of is this. Each library lives in its own directory, with a test directory beneath it. I've added an F90 file containing a module to one of the directories, which I'll call low_library. The contents of this directory are something like:
low_library:
CMakeList.txt
file1.cc
file1.hh
file2.cc
file2.hh
my_module.f90
test:
CMakeList.txt
test1.cc
test2.cc
test3.cc
my_module_test.f90
except many more .cc and .hh files. In the CMakeList.txt file for the library directory, I have instructions that include
add_library(low_library STATIC "")
target_sources(low_library
PUBLIC:
file1.hh
file2.hh
PRIVATE:
file1.cc
file2.cc
)
There's more but it's not obviously relevant.
So the first question is where to put my_module.f90. I want my_module.f90.o to be included in the liblow_library.a file but I need the my_module.mod file to be visible to other libraries I'm building (and to users of the library set). So I add the line
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/fortran_modules)
towards the top of my CMakeList.txt file, add my_module.f90 to the PRIVATE part of the target_sources() PUBLIC list, and ... sigh ... the build system puts the .mod file in the build directory, and not in ${CMAKE_INSTALL_PREFIX}/fortran_modules. The other libraries can't see it and fail to build.
So now I put my_module.f90 in the PUBLIC part of target_sources() and try again. This time the module files goes where I expected it, my test directory can see it and builds successfully, and I'm happy until I move on to building the next library, in directory high_library which depends on low_library. The build comes up with the truly bizarre error:
f951: Fatal Error: Can't rename module file â/scratch/kgbudge/develop/install/fortran_modules/cta_mesh_generator.mod0â to â/scratch/kgbudge/develop/install/fortran_modules/cta_mesh_generator.modâ: No such file or directory
Looking at the rest of the trace, it appears that with my_module.g90 in the public interface of low_library, the build for high_library ignores what's already in my ${CMAKE_INSTALL_PREFIX}/fortran_modules and builds its own copy of the d-mned .mod file in ${CMAKE_INSTALL_PREFIX}/fortran_modules. Which, since we have high-powered build servers and always build in parallel (make -j16 is typical) means a race condition between competing build jobs.
Okay, I know. I needed to include the line
target_include_directories(low_library PUBLIC ${CMAKE_INSTALL_PREFIX}/fortran_modules)
near start of the CMakeLists.txt file for high_library so it knows where to find the modules and wont' try to build its own. Except this doesn't help.
I can find nothing online that gives me any clues what is going on or how to resolve it.

It looks like the problem is that I had my
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/fortran_modules)
only in the libraries that produced or consumed the new modules. But other libraries used the library containing the module and needed to see a copy of the module even though they weren't actually using the module. I think.
Anyway, moving this line into the root CMakeLists.txt allows me to build the whole library successfully. I still seem some warnings:
f951: Warning: Nonexistent include directory â/srcâ [-Wmissing-include-dirs]
but at least it all builds.

Related

Missing dll files error in Objective-C programs

I am a beginner in Objective-C language. I have downloaded and installed GNUstep msys and GNUstep core and installed them in order, as mentioned in the downloads page of GNUstep.
But, I think that the installation isn't correct, because whenever I try to compile an Objective-C source file, it shows fatal error Foundation/Foundation.h file not found. Means, due to some reasons, the path to the header files isn't valid.
Although I am now successfully able to compile the source file with the -I and -L options, I faced another problem. After compilation, when I run the compiled exe file, it shows an error that many dll files are missing, such as objc-4.dll, gnustep-base-1_24.dll to name a few of them. But, I found all of these files present under the /GNUstep/System/Tools folder. When I copied these dll files to my main working (home) directory, it runs successfully without any errors.
Why is this happening? All the tutorials I found on the internet shows very simply the compiling and running of Objective-C programs in Windows without changing so many things. Am I missing something? I have searched many times in StackOverflow and also on the internet, but none of those solved this problem. Please help me and thanks in advance.
P.S. - I have installed GNUstep in the default C:/GNUstep/ folder and included the C:/GNUstep/bin/ and C:/GNUstep/msys/1.0/bin/ folders in the PATH environment variable.
I noticed that there are more than one gcc.exe files present on my system for three different programming language compilers and their parent folders are included in the PATH environment variable. So, the gcc command conflicted with those three executables and therefore, the path to the dll files become invalid.
So, I had to move the GNUstep's bin directory to the top of the PATH environment variable to ensure that the GNUstep's gcc executable is used. And now, everything works like a charm.

How to let some file to be visiable in QtCreator

I'm using cmake to configure my project. It seems QtCreator only show those files referred by add_executable, add_library and configure_file. Other files in project directory are not visiable in the Projects panel.
Although we can still visit those files by file->open, it make me feel bad that many important source files are not visiable in the Projects panel. So...
How does QtCreator decide whether to show a file?
Is there any cmake command that can make arbitrary file to be visiable in QtCreator?
=======================
Some additional info:
My project is a C++ library with PerlXS interface. XS code is preprocessed into C code by xsubpp, and this action is added into cmake project via add_custom_target. However, the XS file is not added into Porjects panel by QtCreator. Besides, a project can have non-source text files such as README, Changes, etc..
I see no reason to put something specific with project, when you can switch to "File System" browser in QtCreator.
But anyway, the answer still the same. If you wish to see something in project - add it to add_executable, add_library.
For example
set(DATA_FILE ${PROJECT_SOURCE_DIR}/build/README.txt)
...
add_executable(${TARGET_NAME} ${SRC_FILES} ${GLB_HDR_FILES} ${DATA_FILE})
And now we can see README.txt in project
Same trick can be done for other files. Just add them to DATA_FILE variable.

Too much exported symbols for a project compiled with CMake and MinGW

I'm trying to compile libzint (a barcode generator) for Windows using CMake and MinGW. The aim is to avoid Visual Studio dependencies. All run fine except that the generated .dll file contains too much exported symbols. I should have only ZBarcode_* functions but in fact pretty much anything that is declared as a variable/constant gets exported (and the resulting .dll file have no version information, I think this is strange.)
Here's how I did the job :
git clone from github repository in D:\Projects\Zint
installed cmake in C:\CMake
installed mingw in C:\MinGW
started cmake-gui, browsed to D:\Projects\Zint
clicked "Configure", choosed "MinGW Makefiles" in the list and "specify native compilers", next I specified the full path to c:\mingw\bin\mingw32-gcc.exe (to be sure...)
Clicked "Configure". It succeeded but it added some variables in red because dependencies where not met (PNG and QT but I don't want them and zint is fine without them)
clicked "Configure" again, everything turned white
clicked "Generate"
closed the cmake-gui
started a console prompt
overrode the path variable environment to C:\mingw\bin only
went to "D:\Projects\Zint" and ran "mingw32-make" then "mingw32-make install"
the libzint.dll and zint.exe were deployed to "C:\Program Files\zint-package\bin"
I used Dependency Walker to have a look at the exported functions and saw that in addition to few ZBarcode_* functions there were also around 400 other symbols and given the source code I saw that these symbols are in fact constants, arrays and other internals of libzint.
Do you know how to configure or tweak things to avoid all these exports ?
Many thanks for your help, regards.
Look in the headers for any macros that contain dllexport. If you find one or more, check that it's not malfunctioning.
Another possibility is that all classes are being exported, instead of just the few functions that are necessary.
If you have grep, do grep -nr dllexport *. This will recursively look in all files. For every hit, it will print the file name, line number, and contents of the line.

"Duplicate class found" - IntelliJ and .class files

I recently imported one of our company's project into IntelliJ Idea (10.5.1). We build and run the project using an ant build script and IntelliJ supports that just fine.
However, IntelliJ seems to have a distinct problem when the compile output directory equals the source code directory, ie .class files are placed in the same directories as their corresponding .java sources.
(Note that I am aware that is not a proper way to go, but tell my boss that. This project is over 15 years old and correspondingly large, too many things depend on it to be this way, there is nothing I can do about that.)
So once things are compiled, IntelliJ detects the .class files and adds them to the project tree. The problem here is that it considers them class declarations, thus I get a "duplicate class found" message for each and every class. This doesn't make me unable to work, but it is extremely annoying as you may guess.
I tried making the IDE ignore .class files, but apparently that makes it not load any classes at all, including the JRE runtime and anything else located inside of .jar files.
Is there any way to make IntelliJ Idea ignore .class files which are in the same location as their .java sources?
Make sure that you've configured the output directory to the source directory, disable the Exclude of the output directory to see your files.
I coped with this same problem when cloning a project from Bitbucket. To solve it in IntelliJ:
Project Structure > Modules > Source > Source folder > <<"Eliminate the unwanted source folder">>
In my case, I had non-implemented classes in one source folder and a second source folder with the implemented classes (same class names).
I deleted one, built again, and the problem got solved.
Give it a try!

Cannot find output .a of Cocoa Static Library (in xcode 4)

I have a project with two targets, one is a Cocoa Static Library, the other is the accompanying test project. Despite building the main project in different ways over and over again, I cannot find the .a file that I expect it to produce.
In fact, I cannot find the build folder associated with the project. I need to link to the library in an app, but cannot do so if I can't find the file to link to.
These properties are correctly set:
(Build Products Path) SYMROOT = build
(Intermediate Build Files Path) OBJROOT = $(SYMROOT)
All tests pass (which means the code MUST be building right?)
Breaking the code causes the build to break - again suggesting that it is building.
Also, the "Products > libproject.a" file is red in the xcode project navigation
I also checked the DerivedData directory, but all the seems to get created is the objects fot the OCunit stuff. Still no .a file against which I can link.
Where is my .a file?
Any help would be much appreciated.
It's probably in ~/Library/Developer/Xcode/DerivedData/ somewhere.