CMake: Not to use /usr/lib64/libXmu.so - cmake

I am new to CMake and Geant4. I am trying to build a project using them.
Also, I am working in a remote cluster. When I cmake, there's no error. But when I do make the error I am getting is,
make[2]: *** No rule to make target '/usr/lib64/libXmu.so', needed by 'PRO_simulation'. Stop.
make[1]: *** [CMakeFiles/PRO_simulation.dir/all] Error 2
make: *** [all] Error 2
however,
ls -rt /usr/lib64/libXmu*
gives:
lrwxrwxrwx. 1 root root 15 Jan 11 2016 /usr/lib64/libXmu.so.6 -> libXmu.so.6.2.0
-rwxr-xr-x. 1 root root 109552 Nov 20 2015 /usr/lib64/libXmu.so.6.2.0
lrwxrwxrwx. 1 root root 16 Jan 11 2016 /usr/lib64/libXmuu.so.1 -> libXmuu.so.1.0.0
-rwxr-xr-x. 1 root root 19440 Nov 20 2015 /usr/lib64/libXmuu.so.1.0.0
Since its a remote cluster I cannot do a link with the name "libXmu.so" (After requesting the cluster authorities, still there's no use), but I can do the link to my local directory.
Now my question is what should I do in cmake such that, it will look for libXmu.so in my local directory instead of /usr/lib64/libXmu.so

First of all, this is a hack and by no means a proper solution, but you can link directly to a .so file: Link .so file to .cpp file via g++ compiling
Open CMakeLists.txt and remove all references to libXmu linking in target_link_libraries for all targets.
Add /home/user/path/to/libXmu.so to the cmake CXX or link flags. More information on how to do that can be found in: How do I add a linker or compile flag in a CMake file? or: Set CFLAGS and CXXFLAGS options using CMake
I would recommend that you first try something such as:
export CFLAGS=/home/user/path/to/libXmu.so
export CXXFLAGS=/home/user/path/to/libXmu.so
Before running cmake. If this fails, open CMakeLists.txt and try to find where extra CFLAGS and CXXFLAGS are defined and add the path to libXmu.so
Another thing that you can do is you can run make VERBOSE=1, which will show you the exact gcc/g++ command issued, copy it in a text editor and replace -lxmu with /home/user/path/to/libXmu.so
I hope at least one of those works.

Related

cmake add_custom_command introduces false dependency unless add_custom_target also used

I'm using cmake to build some libraries, all of which generate some of their files.
I've created the generated files using add_custom_command(), but I've discovered something which seems like a false dependency. If a downstream library has a generated file and links to an upstream library, the downstream library sources will not start to compile until the upstream library is completely built. With many libraries (more than 50) in my project, this false dependency causes serialization in the build.
What's curious is that I also noticed that if an explicit add_custom_target() for the generated file is used with add_dependencies(), the false dependency no longer exists, and the files in the downstream library will compile concurrently with the ones in the upstream library. So I have a workaround, but is this expected behavior?
Using Cmake 1.19, Ninja 1.10.2.
The following is a minimal CMakeLists.txt file that shows what happens. The WORKS option conditionally adds the add_custom_target() and add_dependencies() clauses which cause it to work (quickly). The files foo.c and bar.c are empty, and I'm building in a subdirectory of the CMakeLists.txt directory.
I put a file called /tmp/x which is a wrapper around cc that sleeps to show the serialization occur:
#!/bin/bash -e
echo "mycc" $(date)
sleep 4
exec /usr/bin/cc $*
Here is the CMakeLists.txt:
cmake_minimum_required(VERSION 3.19)
project(test)
option(WORKS "false dependency gone if WORKS set to ON" OFF)
add_library(foo
foo.c
)
add_library(bar
bar.c
bargen.h
)
target_include_directories(bar PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
add_custom_command(OUTPUT bargen.h
COMMAND touch bargen.h
)
if (${WORKS})
add_custom_target(generate_file
DEPENDS bargen.h
)
add_dependencies(bar generate_file)
endif()
target_link_libraries(bar PUBLIC foo)
Build it like this and you will see the serialization: bar.c will not start to compile until after foo.c has finished compiling (in fact, not until after the foo library is built). (I'm explicitly choosing '-j 4' to ensure Ninja will try to build in parallel).
cmake -DWORKS=OFF -G Ninja -DCMAKE_C_COMPILER=/tmp/x .. && ninja clean && ninja -j 4 -v | grep mycc
This shows the following output:
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/rhb/Downloads/cmake-anomaly/build
[1/1] Cleaning all built files...
Cleaning... 5 files.
mycc Sat Jan 2 15:15:25 EST 2021
mycc Sat Jan 2 15:15:29 EST 2021
Now build it like this and you'll see that bar.c compiles concurrently with foo.c:
cmake -DWORKS=ON -G Ninja -DCMAKE_C_COMPILER=/tmp/x .. && ninja clean && ninja -j 4 -v | grep mycc
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/rhb/Downloads/cmake-anomaly/build
[1/1] Cleaning all built files...
Cleaning... 5 files.
mycc Sat Jan 2 15:15:37 EST 2021
mycc Sat Jan 2 15:15:37 EST 2021
This was reported as a cmake issue and recently fixed with a new argument to add_custom_command. This fix will be released with the next cmake version (3.27).
DEPENDS_EXPLICIT_ONLY
.. versionadded:: 3.27
Indicate that the command's DEPENDS argument represents all files
required by the command and implicit dependencies are not required.
Without this option, if any target uses the output of the custom command,
CMake will consider that target's dependencies as implicit dependencies for
the custom command in case this custom command requires files implicitly
created by those targets.
Only the Ninja Generators actually use this information to remove
unnecessary implicit dependencies.

ExternalProject_Add for Makefile project error during build

I am trying to add Postgresql as a dependency for my project for which I am using ExternalProject module to download the source from github and build, but the build step fails when running from cmake (cmake --build .). Configure step seems to succeed and if I go to the Build directory under EP_BASE and do a make it runs successfully. I get the following error during build:
<...>/Source/postgresql_external/src/common/relpath.c:21:10: fatal error: catalog/pg_tablespace_d.h: No such file or directory
21 | #include "catalog/pg_tablespace_d.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[5]: *** [<builtin>: relpath.o] Error 1
make[4]: *** [Makefile:42: all-common-recurse] Error 2
make[3]: *** [GNUmakefile:11: all-src-recurse] Error 2
My external project add looks like the following:
ExternalProject_Add(postgresql_external
GIT_REPOSITORY https://github.com/postgres/postgres.git
GIT_TAG REL_12_4
CONFIGURE_COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR>
LOG_CONFIGURE 1
LOG_BUILD 1
LOG_INSTALL 1
)
This is running on Ubuntu 20.04 LTS, with cmake 3.16.3, gcc 9.3.0
try
ExternalProject_Get_Property(postgresql_external install_dir)
include_directories(${install_dir}/include)
I guess, you haven't propagate include directory to your target yet, but it is evtl. known to your system (thus successful call of manually called make)
Try the following code, it works for me. PotgreSQL uses MAKELEVEL variable to generate header files via perl. When you call make directly it works as expected. But it seems that cmake adds more levels to PotgreSQL's root make, so headers are not generated.
CONFIGURE_COMMAND ./configure <your options>
BUILD_IN_SOURCE 1
BUILD_COMMAND $(MAKE) MAKELEVEL=0

Can not link libuuid when using CMake toolchain file to cross-compile Azure IoTHub SDK

I don't know how to write CMake toolchain-file properly to build Azure IoTHub SDK v1.2.10 successfully.
This is my command:
azure-iot-sdk-c/build_all/linux# ./build.sh --no-amqp --no-http --no_uploadtoblob --no-logging --toolchain-file mytoolchain.cmake
And here is the build result, ld cannot find -luuid:
Scanning dependencies of target iothub_convenience_sample
[ 69%] Building C object iothub_client/samples/iothub_convenience_sample/CMakeFiles/iothub_convenience_sample.dir/iothub_convenience_sample.c.o
[ 70%] Building C object iothub_client/samples/iothub_convenience_sample/CMakeFiles/iothub_convenience_sample.dir/__/__/__/certs/certs.c.o
[ 71%] Linking C executable iothub_convenience_sample
/usr/local/bin/compile_tool/arm-2010q1/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/../../../../arm-none-linux-gnueabi/bin/ld: cannot find -luuid
collect2: ld returned 1 exit status
iothub_client/samples/iothub_convenience_sample/CMakeFiles/iothub_convenience_sample.dir/build.make:128: recipe for target 'iothub_client/samples/iothub_convenience_sample/iothub_convenience_sample' failed
make[2]: *** [iothub_client/samples/iothub_convenience_sample/iothub_convenience_sample] Error 1
CMakeFiles/Makefile2:1327: recipe for target 'iothub_client/samples/iothub_convenience_sample/CMakeFiles/iothub_convenience_sample.dir/all' failed
make[1]: *** [iothub_client/samples/iothub_convenience_sample/CMakeFiles/iothub_convenience_sample.dir/all] Error 2
Makefile:140: recipe for target 'all' failed
make: *** [all] Error 2
Below is my toolchain-file:
INCLUDE(CMakeForceCompiler)
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER /usr/local/bin/compile_tool/arm-2010q1/bin/arm-none-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER /usr/local/bin/compile_tool/arm-2010q1/bin/arm-none-linux-gnueabi-g++)
# set OpenSSL path
SET(OPENSSL_SSL_LIBRARY /myspace/application/openssl/libssl.so)
SET(OPENSSL_CRYPTO_LIBRARY /myspace/application/openssl/libcrypto.so)
SET(OPENSSL_INCLUDE_DIR /myspace/application/openssl/include)
# I can use INCLUDE_DIRECTORIES to find uuid.h
INCLUDE_DIRECTORIES(/myspace/application/libuuid/include)
# But I can't link libuuid by setting CMAKE_FIND_ROOT_PATH... Why?
SET(CMAKE_FIND_ROOT_PATH /myspace/application/libuuid/lib)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
I've downloaded libuuid sources and built it into /myspace/application/libuuid/lib/:
root#my-pc:/myspace/application/libuuid/lib# ls -l
total 116
-rw-r--r-- 1 root root 63258 十一 9 13:57 libuuid.a
-rwxr-xr-x 1 root root 953 十一 9 13:57 libuuid.la
lrwxrwxrwx 1 root root 16 十一 9 13:57 libuuid.so -> libuuid.so.1.0.0
lrwxrwxrwx 1 root root 16 十一 9 13:57 libuuid.so.1 -> libuuid.so.1.0.0
-rwxr-xr-x 1 root root 41893 十一 9 13:57 libuuid.so.1.0.0
drwxr-xr-x 2 root root 4096 十一 9 13:57 pkgconfig
However, if I manually copy libuuid.so.1 and libuuid.so.1.0.0 to the path within my cross-compiler(/usr/local/bin/compile_tool/arm-2010q1/arm-none-linux-gnueabi/lib), it can successfully link libuuid.
So, I think there must be something wrong in my toolchain-file. I've tried to use CMAKE_EXE_LINKER_FLAGS, CMAKE_SHARED_LINKER_FLAGS, link_directories, and link_libraries, all of above failed.
I hope somebody can teach me how to improve my toolchain-file. Thanks!
PS. I don't want to modify Azure IoTHub sources in order to keep it unchanged and easy to maintain.
I have installed compiled libuuid library in cross compiler default path. I use aarch64-linux-gnu so default path will be /usr/aarch64-linux-gnu/

compiling mono 3.10.0 on Centos 6.6 fails

I'm trying to compile a mono release 3.10.0 onto a clean Centos server. I'd rather not try the master, looks like it's build is failing every time I look at it.
So I tried to compile mono like this:
wget https://github.com/mono/mono/archive/mono-3.10.0.tar.gz
tar xvfz mono-3.10.0.tar.gz
cd mono-mono-3.10.0/
./autogen.sh
make get-monolite-latest
This is when I got an error about a missing monolite tarball (more info here: https://bugzilla.xamarin.com/show_bug.cgi?id=16687)
So I found a working url (according to previous link it should work with mono 3.10.0) for one so this is how I continued:
make get-monolite-latest monolite_url=http://storage.bos.xamarin.com/mono-dist-master/1b/1b41fd76350367453c8100f8bd0e7242105c6d39/monolite-111-latest.tar.gz
make EXTERNAL_MCS=${PWD}/mcs/class/lib/monolite/basic.exe
Anyway, this resulted in error:
/usr/local/src/mono-mono-3.10.0/mcs/class/lib/monolite/basic.exe: /usr/local/src/mono-mono-3.10.0/mcs/class/lib/monolite/basic.exe: cannot execute binary file
make[6]: *** [build/deps/basic-profile-check.exe] Error 126
*** The compiler '/usr/local/src/mono-mono-3.10.0/mcs/class/lib/monolite/basic.exe' doesn't appear to be usable.
*** Trying the 'monolite' directory.
Bootstrap compiler: Mono C# compiler version 3.6.1.0
./../jay/jay: 7 shift/reduce conflicts.
mkdir -p -- ../class/lib/basic/
make[7]: *** No rule to make target `../../external/ikvm/reflect/*.cs', needed by `../class/lib/basic/basic.exe'. Stop.
make[6]: *** [do-all] Error 2
make[5]: *** [all-recursive] Error 1
make[4]: *** [profile-do--basic--all] Error 2
make[3]: *** [profiles-do--all] Error 2
make[2]: *** [all-local] Error 2
make[2]: Leaving directory `/usr/local/src/mono-mono-3.10.0/runtime'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/usr/local/src/mono-mono-3.10.0'
make: *** [all] Error 2
So, why "cannot execute binary file" and what can I do about it? I'm running as root so there shouldn't be any permission issues. Also:
# ls -la /usr/local/src/mono-mono-3.10.0/mcs/class/lib/monolite/
total 8048
drwxr-xr-x 2 root root 4096 Jun 2 2014 .
drwxr-xr-x 3 root root 4096 Jan 9 16:21 ..
-rwxr-xr-x 1 root root 298496 Jun 2 2014 Mono.Security.dll
-rwxr-xr-x 1 root root 126464 Jun 2 2014 System.Configuration.dll
-rwxr-xr-x 1 root root 283136 Jun 2 2014 System.Core.dll
-rwxr-xr-x 1 root root 131072 Jun 2 2014 System.Security.dll
-rwxr-xr-x 1 root root 1291264 Jun 2 2014 System.Xml.dll
-rwxr-xr-x 1 root root 1681408 Jun 2 2014 System.dll
-rwxr-xr-x 1 root root 1743360 Jun 2 2014 basic.exe
-rwxr-xr-x 1 root root 2631168 Jun 2 2014 mscorlib.dll
What's wrong here?
EDIT:
Some progress, I was able to achieve a almost-working mono installation. I needed to do the following steps:
git clone -b mono-3.10.0-branch https://github.com/mono/mono.git
git submodule init
git submodule update
./autogen.sh --with-ikvm-native=no
make get-monolite-latest monolite_url=http://storage.bos.xamarin.com/mono-dist-master/1b/1b41fd76350367453c8100f8bd0e7242105c6d39/monolite-111-latest.tar.gz
make EXTERNAL_MCS=${PWD}/mcs/class/lib/monolite/basic.exe
When cloning a 3.10.0 branch the clone is incomplete, some submodules are missing. You need to run git submodule init and git submodule update to get mono compiling.
These steps had mono compiling and installing without errors, but running .Net software is a whole different matter. I still get exceptions when trying to run my console application:
System.InvalidProgramException: Invalid IL code in System.ComponentModel.Composition.Hosting.DirectoryCatalog:.ctor (string): method body is empty.
Well, the compiling part of the question has been resolved so I guess this can be marked as answered.
Got mono compiling according to my edit in the question. I think I had messed something with either file permissions or the basic.exe had not been there in the first place.
The steps I gave in my edit got my installation working.

embedding mono sample: error while loading shared libraries: libmonoboehm-2.0.so.1

i've installed mono on centos 6 via make && make install from source
when i tried this sample:
https://github.com/mono/mono/blob/master/samples/embed/teste.c
no error occured during the compilation, but when i run i got this:
[root#WOH_Test t01]# gcc -o teste teste.c `pkg-config --cflags --libs mono-2` -lm
[root#WOH_Test t01]# mcs test.cs
[root#WOH_Test t01]# ./teste test.exe
./teste: error while loading shared libraries: libmonoboehm-2.0.so.1: cannot open shared object file: No such file or directory
i can't figure where the problem is, any clue?
What do you have in /usr/local/lib? If you didn't use the --prefix option while running autogen.sh before the command make the libraries should be localed in /usr/local/lib. You should see in that directory something like this:
me#mypc:/usr/local/lib$ ls -lah libmono-2.0.*
lrwxrwxrwx. 1 me me 18 dic 19 00:38 libmono-2.0.a -> libmonoboehm-2.0.a
lrwxrwxrwx. 1 me me 19 dic 19 00:38 libmono-2.0.la -> libmonoboehm-2.0.la
lrwxrwxrwx. 1 me me 19 dic 19 00:38 libmono-2.0.so -> libmonoboehm-2.0.so
lrwxrwxrwx. 1 me me 21 dic 19 00:38 libmono-2.0.so.1 -> libmonoboehm-2.0.so.1
lrwxrwxrwx. 1 me me 25 dic 19 00:38 libmono-2.0.so.1.0.0 -> libmonoboehm-2.0.so.1.0.0
If you can see the above libraries in /usr/local/lib your problem is related to where is ld searching for libraries. From this question: CentOS /usr/local/lib system wide $LD_LIBRARY_PATH I guess Centos6 does not have by default configuration for /usr/local/lib. If it is your case, just use the provided solutions in that question (any of them) and your program should work fine.
EDIT
From your comment if you want libmonoboehm-2.0.so.1 in the same path as the teste program and you do not want to touch anything else in your Centos6 you could do something like the following:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/teste/binary
./teste test.exe
But I wonder what output do you have when you run this command: pkg-config --cflags --libs mono-2 (it seems as if you already had a mono installation in your Centos6)
Anyhow, if you can modify your Centos6 the best is this answer: CentOS /usr/local/lib system wide $LD_LIBRARY_PATH. You do that once and you will be able to run any mono program without having to mess with the LD_LIBRARY_PATH environment variable. In your case you should do the following:
1. Edit /etc/ld.so.conf
2. Write this: /opt/mono/lib
3. Run ldconfig -v as root
4. Your Centos6 is ready to run your mono programs whenever you wish (even if you restart your Centos6 machine)
END EDIT