CMAKE AIX xlc compiler not getting used - c++

I am trying to use the xlc compiler for my cpp code on AIX.
I want the cc compiler for my C code
output:
user#AIX> cmake -DCMAKE_CXX_COMPILER=/usr/vac/bin/xlc ..
-- The C compiler identification is XL 11.1.0
-- The CXX compiler identification is XL 11.1.0
-- Check for working C compiler: /usr/vac/bin/cc
-- Check for working C compiler: /usr/vac/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/vac/bin/xlc
-- Check for working CXX compiler: /usr/vac/bin/xlc -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
but when I run make ( right after the above output), it seems to be using the gcc compiler.
user#AIX> make
[ 0%] Building CXX object ../libs/shrxml/CMakeFiles/shrxml.dir/XML.cpp.o
gcc: unrecognized option '-+'
gcc: unrecognized option '-qthreaded'
gcc: unrecognized option '-qhalt=e'
gcc: unrecognized option '-qnamemangling=v6'
gcc: unrecognized option '-qmaxmem=9216'
gcc: unrecognized option '-qnamemangling=v6'
gcc: unrecognized option '-qmaxmem=9216'
gcc: unrecognized option '-qpic'
In file included from /opt/freeware/lib/gcc/powerpc-ibm-
aix6.1.0.0/4.4.5/include/c++/backward/strstream:47,
from
/home/user/workspace/bitbucket/ark/src/libs/shrxml/XML.cpp:105:
/opt/freeware/lib/gcc/powerpc-ibm-
aix6.1.0.0/4.4.5/include/c++/backward/backward_warning.h:28:2: warning:
#warning This file includes at least one deprecated or antiquated header
which may be removed without further notice at a future date. Please use a
non-deprecated interface with equivalent functionality instead. For a
listing of replacement headers and interfaces, consult the file
backward_warning.h. To disable this warning use -Wno-deprecated.
I have tried adding the set inside my CMakeLists.txt file
set(CMAKE_CXX_COMPILER /usr/vac/bin/xlc CACHE PATH "" FORCE)
set(CMAKE_CC_COMPILER /usr/vac/bin/cc CACHE PATH "" FORCE)
I have also exported the environment variable:
user#AIX> echo $CMAKE_CXX_COMPILER
/usr/vac/bin/xlc
user#AIX>
Any thoughts?
There are no links for cc or xlc in the /usr/vac/bin directory.
When I grep for gcc and xlc in the shrxlm directory all I can find is gcc. Why isn't cmake honoring my request for the xlc compiler?

Check the cc symlink on your system to make sure it points to XL and not gcc. Do a which cc and then ls -l that.

According to the CMake FAQ "How do I use a different compiler?" section, there are 3 methods. It looks like you have tried to use all 3, including Method 3 (set()), which is marked "avoid".
Could you try Method 1: use environment variables again, but this time with the environment variables listed there, CC (for C) and CXX (for C++) environment variables?

Related

How should I setup script-based source generation with CMake?

I'm managing the build of a certain C++ repository using CMake. In this repository, and among other things, I have a bunch of .hpp files in a directory, and for each of these, I need to compile a generated bit of source code, which depends on its contents.
Naively, I would do this by generating a correspond .cpp file, and include that file in the source files of the CMake target for the library or executable I'm building. Now, since I don't actually need the source files themselves, I could theoretically just arrange for the compiler to get its source from the command-line instead.
My question: How would I set up this source generation and compilation, using CMake as idiomatically as possible?
Notes:
Assume I have, say, a bash script which can read the .hpp and generate the .cpp on the standard output.
CMake version 3.24 or whichever you like.
Should work on Unix-like operating systems, and hopefully on Windows-like OSes other than the fact that the bash script will fail.
Please comment if additional information is necessary to answer my question.
Let's assume for the sake of portability that you have a Python script, rather than a bash script that manages your code generation. Let's say that it takes two arguments: the source .hpp file and the destination .cpp file. We'll assume it is in your source tree under ./tools/codegen.py.
Now let's assume that your .hpp files are in ./src/genmod for "generated module" because the sources for these headers are generated by codegen.py.
Finally, we'll assume there's a final executable target, app, with a single source file, ./src/main.cpp.
Here's a minimal build that will work for this, with some step-by-step discussion.
We start with some boring boilerplate.
cmake_minimum_required(VERSION 3.24)
project(example)
This probably works on earlier versions, I just haven't tested it, so YMMV. Now we'll create the executable target and link it to our generated sources preemptively. Note that the dependent target does not need to exist before calling target_link_libraries.
add_executable(app src/main.cpp)
target_link_libraries(app PRIVATE genmod)
Now we'll find a Python interpreter and write down an absolute path to the codegen tool.
find_package(Python3 REQUIRED)
set(codegen_py "${CMAKE_CURRENT_SOURCE_DIR}/tools/codegen.py")
Next we'll construct the list of input headers. I'm imagining there are three: A.hpp, B.hpp, and C.hpp.
set(input_headers A.hpp B.hpp C.hpp)
list(TRANSFORM input_headers PREPEND src/genmod/)
I used list(TRANSFORM) here to save some typing. Now we'll just create an object library called genmod, which will "hold" the objects for the generated C++ files.
add_library(genmod OBJECT)
And now comes the real meat. For each of the headers, ...
foreach (header IN LISTS input_headers)
we'll construct absolute paths to the header and generated source files ...
string(REGEX REPLACE "\\.hpp$" ".cpp" gensrc "${header}")
set(header "${CMAKE_CURRENT_SOURCE_DIR}/${header}")
set(gensrc "${CMAKE_CURRENT_BINARY_DIR}/${gensrc}")
and then write a custom command that knows how to call codegen.py. We specify the outputs, command arguments, and dependencies. Don't forget to include the generator script as a dependency, and never forget to pass VERBATIM to ensure consistent, cross-platform, argument quoting.
add_custom_command(
OUTPUT "${gensrc}"
COMMAND Python3::Interpreter "${codegen_py}" "${header}" "${gensrc}"
DEPENDS "${header}" "${codegen_py}"
VERBATIM
)
Finally, we attach this source to genmod.
target_sources(genmod PRIVATE "${gensrc}")
endforeach ()
We can test this build using Ninja's dry-run feature to make sure the commands look correct.
$ cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Python3: /home/reinking/.venv/default/bin/python3.9 (found version "3.9.2") found components: Interpreter
-- Configuring done
-- Generating done
-- Build files have been written to: /home/reinking/test/build
$ cmake --build build -- -nv
[1/8] cd /home/reinking/test/build && /home/reinking/.venv/default/bin/python3.9 /home/reinking/test/tools/codegen.py /home/reinking/test/src/genmod/A.hpp /home/reinking/test/build/src/genmod/A.cpp
[2/8] cd /home/reinking/test/build && /home/reinking/.venv/default/bin/python3.9 /home/reinking/test/tools/codegen.py /home/reinking/test/src/genmod/B.hpp /home/reinking/test/build/src/genmod/B.cpp
[3/8] cd /home/reinking/test/build && /home/reinking/.venv/default/bin/python3.9 /home/reinking/test/tools/codegen.py /home/reinking/test/src/genmod/C.hpp /home/reinking/test/build/src/genmod/C.cpp
[4/8] /usr/bin/c++ -O3 -DNDEBUG -MD -MT CMakeFiles/genmod.dir/src/genmod/A.cpp.o -MF CMakeFiles/genmod.dir/src/genmod/A.cpp.o.d -o CMakeFiles/genmod.dir/src/genmod/A.cpp.o -c /home/reinking/test/build/src/genmod/A.cpp
[5/8] /usr/bin/c++ -O3 -DNDEBUG -MD -MT CMakeFiles/genmod.dir/src/genmod/B.cpp.o -MF CMakeFiles/genmod.dir/src/genmod/B.cpp.o.d -o CMakeFiles/genmod.dir/src/genmod/B.cpp.o -c /home/reinking/test/build/src/genmod/B.cpp
[6/8] /usr/bin/c++ -O3 -DNDEBUG -MD -MT CMakeFiles/genmod.dir/src/genmod/C.cpp.o -MF CMakeFiles/genmod.dir/src/genmod/C.cpp.o.d -o CMakeFiles/genmod.dir/src/genmod/C.cpp.o -c /home/reinking/test/build/src/genmod/C.cpp
[7/8] /usr/bin/c++ -O3 -DNDEBUG -MD -MT CMakeFiles/app.dir/src/main.cpp.o -MF CMakeFiles/app.dir/src/main.cpp.o.d -o CMakeFiles/app.dir/src/main.cpp.o -c /home/reinking/test/src/main.cpp
[8/8] : && /usr/bin/c++ -O3 -DNDEBUG CMakeFiles/genmod.dir/src/genmod/A.cpp.o CMakeFiles/genmod.dir/src/genmod/B.cpp.o CMakeFiles/genmod.dir/src/genmod/C.cpp.o CMakeFiles/app.dir/src/main.cpp.o -o app && :
And indeed we can see that the commands are what we'd naturally expect them to be.

Trouble running LLVM examples

I've been struggling with this for longer than I care to admit and would really appreciate some help.
I'm trying to do a project which involves building a linker and scheduler, and thought if I could use some of the functionality that's already been build into LLVM that would be great. I'm using LLVM 10. To get started I did some reading and tried to build this example. Because I plan on embedding LLVM into another project, used this as a reference for 'how to build' the example (see below). I figured the dependencies are just the components from the example CMakeLists.txt.
If I'm not mistaken, I'm getting a linker error and that the component list is the problem, but I'm struggling to resolve it. The way it seems LLVM does linking is by mapping a component name to an library file, but since I don't know which missing library might be causing it I'm stuck. Also, I don't know what llvm_libs is, but adding it to the component list seemed to resolve some of the linker errors I was getting originally. Also also, changing the order of the component list will give me different amounts of errors, which absolutely confounds me.
CMakeLists.txt
cmake_minimum_required(VERSION 3.13.4)
project(HowToUseJIT)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
# Set your project compile flags.
# E.g. if using the C++ header files
# you will need to enable C++11 support
# for your compiler.
message(STATUS "INCLUDE ${LLVM_INCLUDE_DIRS}")
include_directories(${LLVM_INCLUDE_DIRS})
message(STATUS "DEFINITIONS ${LLVM_DEFINITIONS}\n${LLVM_DEFINITIONS_LIST}")
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})
# Now build our tools
add_executable(HowToUseJIT HowToUseJIT.cpp)
# Find the libraries that correspond to the LLVM components
# that we wish to use
llvm_map_components_to_libnames(llvm_libs support core interpreter nativecodegen executionengine)
# Link against LLVM libraries
message(STATUS "LIBS ${llvm_libs}")
target_link_libraries(HowToUseJIT ${llvm_libs})
Then from a subdir I run
$ cmake ../
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jeremy_arsenault/Documents/random/llvm_examples/HowToUseJIT/build
$ cmake --build .
[ 50%] Building CXX object CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o
[100%] Linking CXX executable HowToUseJIT
/usr/bin/ld: CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o: in function `main':
HowToUseJIT.cpp:(.text+0x4b7): undefined reference to `llvm::EngineBuilder::EngineBuilder(std::unique_ptr<llvm::Module, std::default_delete<llvm::Module> >)'
/usr/bin/ld: HowToUseJIT.cpp:(.text+0x4dc): undefined reference to `llvm::EngineBuilder::~EngineBuilder()'
/usr/bin/ld: HowToUseJIT.cpp:(.text+0x693): undefined reference to `llvm::EngineBuilder::~EngineBuilder()'
/usr/bin/ld: CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o: in function `llvm::EngineBuilder::create()':
HowToUseJIT.cpp:(.text._ZN4llvm13EngineBuilder6createEv[_ZN4llvm13EngineBuilder6createEv]+0x18): undefined reference to `llvm::EngineBuilder::selectTarget()'
/usr/bin/ld: HowToUseJIT.cpp:(.text._ZN4llvm13EngineBuilder6createEv[_ZN4llvm13EngineBuilder6createEv]+0x2a): undefined reference to `llvm::EngineBuilder::create(llvm::TargetMachine*)'
/usr/bin/ld: CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o: in function `llvm::IRBuilderDefaultInserter::IRBuilderDefaultInserter()':
HowToUseJIT.cpp:(.text._ZN4llvm24IRBuilderDefaultInserterC2Ev[_ZN4llvm24IRBuilderDefaultInserterC5Ev]+0xf): undefined reference to `vtable for llvm::IRBuilderDefaultInserter'
/usr/bin/ld: CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o: in function `llvm::InitializeNativeTarget()':
HowToUseJIT.cpp:(.text._ZN4llvm22InitializeNativeTargetEv[_ZN4llvm22InitializeNativeTargetEv]+0x9): undefined reference to `LLVMInitializeX86TargetInfo'
/usr/bin/ld: HowToUseJIT.cpp:(.text._ZN4llvm22InitializeNativeTargetEv[_ZN4llvm22InitializeNativeTargetEv]+0xe): undefined reference to `LLVMInitializeX86Target'
/usr/bin/ld: HowToUseJIT.cpp:(.text._ZN4llvm22InitializeNativeTargetEv[_ZN4llvm22InitializeNativeTargetEv]+0x13): undefined reference to `LLVMInitializeX86TargetMC'
/usr/bin/ld: CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o: in function `llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>::~IRBuilder()':
HowToUseJIT.cpp:(.text._ZN4llvm9IRBuilderINS_14ConstantFolderENS_24IRBuilderDefaultInserterEED2Ev[_ZN4llvm9IRBuilderINS_14ConstantFolderENS_24IRBuilderDefaultInserterEED5Ev]+0x1c): undefined reference to `llvm::IRBuilderDefaultInserter::~IRBuilderDefaultInserter()'
/usr/bin/ld: CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o: in function `llvm::IRBuilderFolder::IRBuilderFolder()':
HowToUseJIT.cpp:(.text._ZN4llvm15IRBuilderFolderC2Ev[_ZN4llvm15IRBuilderFolderC5Ev]+0xf): undefined reference to `vtable for llvm::IRBuilderFolder'
/usr/bin/ld: CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o: in function `llvm::ConstantFolder::ConstantFolder()':
HowToUseJIT.cpp:(.text._ZN4llvm14ConstantFolderC2Ev[_ZN4llvm14ConstantFolderC5Ev]+0x1f): undefined reference to `vtable for llvm::ConstantFolder'
/usr/bin/ld: CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o: in function `llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>::IRBuilder(llvm::BasicBlock*, llvm::MDNode*, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >)':
HowToUseJIT.cpp:(.text._ZN4llvm9IRBuilderINS_14ConstantFolderENS_24IRBuilderDefaultInserterEEC2EPNS_10BasicBlockEPNS_6MDNodeENS_8ArrayRefINS_17OperandBundleDefTIPNS_5ValueEEEEE[_ZN4llvm9IRBuilderINS_14ConstantFolderENS_24IRBuilderDefaultInserterEEC5EPNS_10BasicBlockEPNS_6MDNodeENS_8ArrayRefINS_17OperandBundleDefTIPNS_5ValueEEEEE]+0xbb): undefined reference to `llvm::IRBuilderDefaultInserter::~IRBuilderDefaultInserter()'
/usr/bin/ld: CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o: in function `llvm::ConstantFolder::~ConstantFolder()':
HowToUseJIT.cpp:(.text._ZN4llvm14ConstantFolderD2Ev[_ZN4llvm14ConstantFolderD5Ev]+0x13): undefined reference to `vtable for llvm::ConstantFolder'
/usr/bin/ld: HowToUseJIT.cpp:(.text._ZN4llvm14ConstantFolderD2Ev[_ZN4llvm14ConstantFolderD5Ev]+0x26): undefined reference to `llvm::IRBuilderFolder::~IRBuilderFolder()'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/HowToUseJIT.dir/build.make:91: HowToUseJIT] Error 1
make[1]: *** [CMakeFiles/Makefile2:77: CMakeFiles/HowToUseJIT.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
If anyone knows what my problem is, has any advice on running these LLVM examples, or knows of any resources that might better my understanding of wtf is happening I will be eternally grateful :). Thanks in advance for any help!
Edit 1: I tried the same procedure on some other examples to see what would happen. On Fibonacci everything build fine then seg faulted on runtime. On ModuleMaker I build fails on undefined reference to main... I'm really bungling something up here I just don't know what.
Edit 2: Thank you for the responses. I'm currently attempting to get everything to build correctly using Alexs advice. Simply using the CMakeLists.txt and building using Ninja did not work :( (I updated the build process outputs above). I was getting similar errors as before. Since Alex mentioned that he needed to use a different version of llvm header files, I figured I'd just build an updated version from source - but LLVM bested me once again. The build from source procedure in the README bombs on every release version I try (I'm running Ubuntu 20.04 lts). I'm starting to think my best bet is to just cherry-pick files and hack something together myself because this is getting to be too much of a headache.
Edit 3: I got it working :)
Solution
Everything ran and built fine when I updated to the newest version of LLVM. I ran into a lot of build problems on Ubuntu 20.04 lts that were a product of missing dependencies. This kind soul posted all the deps he needed to install in order to build llvm without errors.
So the following build worked for me and should hopefully be a model for you re: how to use CMake...
cmake_minimum_required(VERSION 3.22)
project(test)
# Find LLVM and the components we require.
find_package(LLVM 10 REQUIRED)
llvm_map_components_to_libnames(
LLVM_LIBRARIES
Core
ExecutionEngine
Interpreter
MC
MCJIT
Support
nativecodegen
)
# Create a wrapper for the LLVM components we need in this
# project. This will allow us to link it to multiple targets
# without duplicating a lot of code. It's too bad that LLVM
# doesn't provide anything like this.
add_library(test::LLVM INTERFACE IMPORTED)
target_include_directories(test::LLVM INTERFACE ${LLVM_INCLUDE_DIRS})
target_compile_definitions(test::LLVM INTERFACE ${LLVM_DEFINITIONS})
target_link_libraries(test::LLVM INTERFACE ${LLVM_LIBRARIES})
# Create our actual executable and link LLVM to it.
add_executable(HowToUseJIT HowToUseJIT.cpp)
target_link_libraries(HowToUseJIT PRIVATE test::LLVM)
Notice the following:
LLVM does not provide its own imported targets (bad)
We therefore create our own imported target to wrap it, test::LLVM.
We add the MC and MCJIT components to the list of components.
We assign the package-provided variables and computed list of libraries to the relevant properties of our imported target.
We always call target_link_libraries with a visibility specifier (they are PRIVATE, INTERFACE, and PUBLIC. Omitting it is none of the above.)
We state the version number of LLVM we require in the find_package call and omit the unnecessary CONFIG argument. Every major version of LLVM breaks the API in significant ways.
At the terminal, I now see:
$ cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /path/to/build
$ cmake --build build/ --verbose
[1/2] /usr/bin/c++ -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -isystem /usr/lib/llvm-10/include -O3 -DNDEBUG -MD -MT CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o -MF CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o.d -o CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o -c /path/to/HowToUseJIT.cpp
[2/2] : && /usr/bin/c++ -O3 -DNDEBUG CMakeFiles/HowToUseJIT.dir/HowToUseJIT.cpp.o -o HowToUseJIT /usr/lib/llvm-10/lib/libLLVMInterpreter.a /usr/lib/x86_64-linux-gnu/libffi.so /usr/lib/llvm-10/lib/libLLVMMCJIT.a /usr/lib/llvm-10/lib/libLLVMExecutionEngine.a /usr/lib/llvm-10/lib/libLLVMRuntimeDyld.a /usr/lib/llvm-10/lib/libLLVMX86CodeGen.a /usr/lib/llvm-10/lib/libLLVMAsmPrinter.a /usr/lib/llvm-10/lib/libLLVMDebugInfoDWARF.a /usr/lib/llvm-10/lib/libLLVMCFGuard.a /usr/lib/llvm-10/lib/libLLVMGlobalISel.a /usr/lib/llvm-10/lib/libLLVMSelectionDAG.a /usr/lib/llvm-10/lib/libLLVMCodeGen.a /usr/lib/llvm-10/lib/libLLVMTarget.a /usr/lib/llvm-10/lib/libLLVMBitWriter.a /usr/lib/llvm-10/lib/libLLVMScalarOpts.a /usr/lib/llvm-10/lib/libLLVMAggressiveInstCombine.a /usr/lib/llvm-10/lib/libLLVMInstCombine.a /usr/lib/llvm-10/lib/libLLVMTransformUtils.a /usr/lib/llvm-10/lib/libLLVMAnalysis.a /usr/lib/llvm-10/lib/libLLVMProfileData.a /usr/lib/llvm-10/lib/libLLVMX86Desc.a /usr/lib/llvm-10/lib/libLLVMObject.a /usr/lib/llvm-10/lib/libLLVMBitReader.a /usr/lib/llvm-10/lib/libLLVMCore.a /usr/lib/llvm-10/lib/libLLVMRemarks.a /usr/lib/llvm-10/lib/libLLVMBitstreamReader.a /usr/lib/llvm-10/lib/libLLVMMCParser.a /usr/lib/llvm-10/lib/libLLVMTextAPI.a /usr/lib/llvm-10/lib/libLLVMX86Utils.a /usr/lib/llvm-10/lib/libLLVMMCDisassembler.a /usr/lib/llvm-10/lib/libLLVMMC.a /usr/lib/llvm-10/lib/libLLVMBinaryFormat.a /usr/lib/llvm-10/lib/libLLVMDebugInfoCodeView.a /usr/lib/llvm-10/lib/libLLVMDebugInfoMSF.a /usr/lib/llvm-10/lib/libLLVMX86Info.a /usr/lib/llvm-10/lib/libLLVMSupport.a -lz -lrt -ldl -ltinfo -lpthread -lm /usr/lib/llvm-10/lib/libLLVMDemangle.a && :
$ ./build/HowToUseJIT
We just constructed this LLVM module:
; ModuleID = 'test'
source_filename = "test"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
define i32 #add1(i32 %AnArg) {
EntryBlock:
%0 = add i32 1, %AnArg
ret i32 %0
}
define i32 #foo() {
EntryBlock:
%0 = tail call i32 #add1(i32 10)
ret i32 %0
}
Running foo: Result: 11
Note: I had to use the sources for HowToUseJIT from a more recent LLVM release (the one from 13.0.0) because the old one has a segfault on some systems. However, that bug is unrelated to the build process.

Set GCC path in makefile

Whenever I am building my package it uses /usr/bin/g++ (system compiler).
I want to build my package with C++11 constructs. I have tried -std=c++11 option but with system compiler it says unrecognized option.
I want to build my package from a different gcc compiler which will get downloaded as part of my package dependency.
So, how can I specify the location of gcc compiler in Makefile?
There are multiple ways to achieve what you are looking for:
Setting the environment variable CXX just for the process that will run make:
$ CXX=/path-to-your-compiler/g++ make
Exporting the environment variable CXX in your shell:
$ CXX=/path-to-your-compiler/g++
$ export CXX
$ make
Setting CXX at make's command-line:
$ make CXX=/path-to-your-compiler/g++
Inside your makefile:
CXX := /path-to-your-compiler/g++
Note that setting the variable at make's command line overrides the other values, and variables set inside the makefile override the ones obtained from the environment (unless the command-line option -e or --environment-overrides is provided).
Inside your makefile, you can still override any value set by other means by using the override directive:
override CXX := /path-to-your-compiler/g++

Cmake: How to add a new compiler ID without patching root modules?

I'm creating cmake toolchain description for my compiler (for example let's name it MYCC) based on clang, so it's identified as Clang during compiler identification:
-- The C compiler identification is Clang 3.8.0
-- The CXX compiler identification is Clang 3.8.0
But MYCC doesn't really supports all the things (flags like -fPIC), that Clang does, and I want it to be identified as MYCC, not Clang. I also want my clients to see:
-- The C compiler identification is MYCC
-- The CXX compiler identification is MYCC
I can't use CMakeForceCompiler because it is deprecated (https://cmake.org/cmake/help/v3.0/module/CMakeForceCompiler.html).
I found that IDs is hardcoded in https://github.com/Kitware/CMake/blob/master/Modules/CMakeCompilerIdDetection.cmake
Is there any way to have my own compiler ID without patching this file?

Why is cmake finding 32-bit libraries instead of 64-bit libs on a 64-bit system?

Problem Description
I'm working on porting several codebases over from Red Hat 5 to 6, and I've run into a cmake issue that I'm completely stumped by.
Cmake is consistently finding the 32-bit versions of libraries under /usr/lib instead of the 64-bit versions under /usr/lib64 on an RHEL6 system, while it correctly detects the lib64 versions on the an RHEL5 system.
Minimal Example
For example, I have a very minimal CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8)
find_library(XTEST X11)
message("Found X11 at ${XTEST}")
On an RHEL6 system, running cmake on this results in:
$ cmake ..
-- The C compiler identification is GNU 4.4.7
-- The CXX compiler identification is GNU 4.4.7
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
Found X11 at /usr/lib/libX11.so
-- Configuring done
-- Generating done
-- Build files have been written to: $HOME/software/64bit_problem/build
(The key part here is the Found X11 at /usr/lib/libX11.so line)
However, if I do the same thing on an RHEL5 system, it correctly detects the /usr/lib64/ version: (Note that I'm clearing out the CMakeCache.txt and other temporary cmake-files in between runs.)
$ cmake ..
-- The C compiler identification is GNU 4.1.2
-- The CXX compiler identification is GNU 4.1.2
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
Found X11 at /usr/lib64/libX11.so
-- Configuring done
-- Generating done
-- Build files have been written to: $HOME/software/64bit_problem/build
Troubleshooting Info
The /usr/lib64 versions of the libraries exist on both systems. Here's the listing on the RHEL6 system:
$ ls /usr/lib64/libX11.so*
/usr/lib64/libX11.so.6 /usr/lib64/libX11.so.6.3.0
And on the RHEL5 system:
$ ls /usr/lib64/libX11.so*
/usr/lib64/libX11.so.6 /usr/lib64/libX11.so.6.3.0
Just to confirm that /usr/lib is indeed the 32-bit versions (also, it's not a symlink to another location):
$ file /usr/lib/libX11.so*
/usr/lib/libX11.so: symbolic link to `libX11.so.6.3.0'
/usr/lib/libX11.so.6: symbolic link to `libX11.so.6.3.0'
/usr/lib/libX11.so.6.3.0: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped
$ file /usr/lib64/libX11.so*
/usr/lib64/libX11.so.6: symbolic link to `libX11.so.6.3.0'
/usr/lib64/libX11.so.6.3.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped
This is probably due to an environment setting somewhere, but I'm a bit stumped as to where. I don't have LD_LIBRARY_PATH, LD_RUN_PATH, or LDFLAGS set. Same for CFLAGS and CXXFLAGS. My user environment should be identical, as my $HOME is an NFS share that's the same on both machines.
/usr/lib isn't in my $PATH, and regardless, limiting my path to a minimal subset doesn't seem to help:
$ export PATH=/bin:/usr/bin:$HOME/local/bin
$ cmake ..
<snip>
Found X11 at /usr/lib/libX11.so
-- Configuring done
<snip>
#SergyA had the excellent suggestion of checking which environment variables were being accessed by using ltrace. strace didn't turn up anything diagnostic from what I could see, but ltrace shows the environment variable access nicely. Here's a quick summary:
$ ltrace -o ltrace_output cmake ..
$ grep getenv ltrace_output
getenv("PWD") = "$HOME/software/64bit_problem"
getenv("PATH") = "/bin:/usr/bin:$HOME/local/bin"
getenv("CMAKE_ROOT") = NULL
getenv("MAKEFLAGS") = NULL
getenv("VERBOSE") = NULL
getenv("CFLAGS") = NULL
getenv("LDFLAGS") = NULL
getenv("LDFLAGS") = NULL
getenv("LDFLAGS") = NULL
getenv("CXXFLAGS") = NULL
getenv("LDFLAGS") = NULL
getenv("LDFLAGS") = NULL
getenv("LDFLAGS") = NULL
cmake-specific Trobleshooting
The cmake version is identical on both machines (in fact, it's the same executable for reasons I'll omit for brevity):
$ cmake --version
cmake version 2.8.11.2
$ which cmake
$HOME/local/bin/cmake
I've tried explicitly enabling FIND_LIBRARY_USE_LIB64_PATHS, but this doesn't seem to make a difference:
cmake_minimum_required(VERSION 2.8)
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS ON)
find_library(XTEST X11)
message("Found X11 at ${XTEST}")
As #Ravi mentioned, this is more likely due to some issue with CMAKE_LIBRARY_PATH, but it's not set, and changing it as either an environment variable or as a cmake variable doesn't seem to help. However, I fully admit I am largely ignorant of the various cmake configuration variables, so it's very likely that I'm missing something obvious here.
One key thing I've recently realized is that it's not all libraries... For example:
cmake_minimum_required(VERSION 2.8)
find_library(PNGTEST png)
message("Found libpng at ${PNGTEST}")
Finds /usr/lib64/libpng.so instead of /usr/lib/libpng.so.
This leads me to think it's something cmake-specific, at any rate.
find_package instead of find_library
Given the library-specific issues I mentioned above, I thought to try finding the entire X11 package instead of a single library (which is really what the codebase I was working with should have done anyway).
However, I'm getting even more confusing results... It seems to be detecting a mix of 64-bit and 32-bit libraries? For example:
cmake_minimum_required(VERSION 2.8)
FIND_PACKAGE(X11 REQUIRED)
message("X11_LIBRARIES: ${X11_LIBRARIES}")
We'll get:
$ cmake ..
<snip>
-- Looking for XOpenDisplay in /usr/lib/libX11.so;/usr/lib/libXext.so
-- Looking for XOpenDisplay in /usr/lib/libX11.so;/usr/lib/libXext.so - not found
<snip>
-- Found X11: /usr/lib/libX11.so
X11_LIBRARIES: /usr/lib64/libSM.so;/usr/lib64/libICE.so;/usr/lib/libX11.so;/usr/lib/libXext.so
-- Configuring done
<snip>
However, if we have a look at these specific libraries in X11_LIBRARIES, they're a mix of 32-bit and 64-bit versions!
$ file /usr/lib64/libSM.so.6.0.1
/usr/lib64/libSM.so.6.0.1: ELF 64-bit LSB shared object, x86-64, <snip>
$ file /usr/lib64/libICE.so.6.3.0
/usr/lib64/libICE.so.6.3.0: ELF 64-bit LSB shared object, x86-64, <snip>
$ file /usr/lib/libX11.so.6.3.0
/usr/lib/libX11.so.6.3.0: ELF 32-bit LSB shared object, Intel 80386, <snip>
$ file /usr/lib/libXext.so.6.4.0
/usr/lib/libXext.so.6.4.0: ELF 32-bit LSB shared object, Intel 80386, <snip>
In summary, what else should I try?
Am I missing a cmake-specific or possibly X11-specific configuration option?
You could try :
list(INSERT 0 CMAKE_SYSTEM_LIBRARY_PATH /usr/lib64)
The full list of variables used by find_library is available in the documentation: https://cmake.org/cmake/help/v3.5/command/find_library.html
It turns out that the root problem is the version suffix and the lack of a symlink to specifically /usr/lib64/libX11.so on the RHEL6 side.
cmake looks specifically for libX11.so and not libX11.so.6 or some other version-specific variant.
In this case, making the symlink wasn't an option, but I was able to prefer the specific version by listing the filename first:
cmake_minimum_required(VERSION 2.8)
find_library(XTEST NAMES libX11.so.6 X11)
message("Found X11 at ${XTEST}")
However, there are undoubtedly a variety of better ways of handling this, and I'd be very interested to hear them if anyone has any better approaches.