Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.7.0-alpha.1] - Unreleased

### Added
### Changed
### Fixed
- `erlang:system_info(system_architecture)` now reports normalized `arch-vendor-os` strings

## [0.7.0-alpha.0] - 2026-03-20

### Added
Expand Down
71 changes: 71 additions & 0 deletions CMakeModules/SystemArchitecture.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#
# This file is part of AtomVM.
#
# Copyright 2026 Peter M. <petermm@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#

function(avm_get_system_architecture_string out_var)
set(options)
set(one_value_args PLATFORM_VENDOR PLATFORM_OS)
cmake_parse_arguments(PARSE_ARGV 1 AVM "${options}" "${one_value_args}" "")

execute_process(
COMMAND ${CMAKE_C_COMPILER} -dumpmachine
OUTPUT_VARIABLE avm_raw_system_architecture
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)

if (avm_raw_system_architecture STREQUAL "")
unset(${out_var} PARENT_SCOPE)
return()
endif()

string(REPLACE "-" ";" avm_system_architecture_parts "${avm_raw_system_architecture}")
list(LENGTH avm_system_architecture_parts avm_system_architecture_length)

if (avm_system_architecture_length EQUAL 1)
list(GET avm_system_architecture_parts 0 avm_architecture)
if (DEFINED AVM_PLATFORM_VENDOR)
set(avm_vendor "${AVM_PLATFORM_VENDOR}")
else()
set(avm_vendor "unknown")
endif()
set(avm_os "unknown")
elseif (avm_system_architecture_length EQUAL 2)
list(GET avm_system_architecture_parts 0 avm_architecture)
if (DEFINED AVM_PLATFORM_VENDOR)
set(avm_vendor "${AVM_PLATFORM_VENDOR}")
else()
set(avm_vendor "unknown")
endif()
list(GET avm_system_architecture_parts 1 avm_os)
else()
list(GET avm_system_architecture_parts 0 avm_architecture)
list(GET avm_system_architecture_parts 1 avm_vendor)
if (DEFINED AVM_PLATFORM_VENDOR AND (avm_vendor STREQUAL "none" OR avm_vendor STREQUAL "unknown"))
set(avm_vendor "${AVM_PLATFORM_VENDOR}")
endif()

list(REMOVE_AT avm_system_architecture_parts 0 1)
string(REPLACE ";" "_" avm_os "${avm_system_architecture_parts}")
endif()

if (DEFINED AVM_PLATFORM_OS)
set(avm_os "${AVM_PLATFORM_OS}")
endif()

string(REPLACE "-" "_" avm_architecture "${avm_architecture}")
string(REPLACE "-" "_" avm_vendor "${avm_vendor}")
string(REPLACE "-" "_" avm_os "${avm_os}")

set(${out_var} "${avm_architecture}-${avm_vendor}-${avm_os}" PARENT_SCOPE)
endfunction()
20 changes: 20 additions & 0 deletions src/libAtomVM/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,26 @@ else()
set(ATOMVM_VERSION ${ATOMVM_BASE_VERSION})
endif()

set(AVM_SYSTEM_ARCHITECTURE_FALLBACK_ARCH "${CMAKE_SYSTEM_PROCESSOR}")
if (AVM_SYSTEM_ARCHITECTURE_FALLBACK_ARCH STREQUAL "")
set(AVM_SYSTEM_ARCHITECTURE_FALLBACK_ARCH "unknown")
endif()
string(REPLACE "-" "_" AVM_SYSTEM_ARCHITECTURE_FALLBACK_ARCH "${AVM_SYSTEM_ARCHITECTURE_FALLBACK_ARCH}")

set(AVM_SYSTEM_ARCHITECTURE_FALLBACK_OS "${CMAKE_SYSTEM_NAME}")
if (AVM_SYSTEM_ARCHITECTURE_FALLBACK_OS STREQUAL "")
set(AVM_SYSTEM_ARCHITECTURE_FALLBACK_OS "unknown")
endif()
if (NOT CMAKE_SYSTEM_VERSION STREQUAL "")
string(APPEND AVM_SYSTEM_ARCHITECTURE_FALLBACK_OS "_${CMAKE_SYSTEM_VERSION}")
endif()
string(REPLACE "-" "_" AVM_SYSTEM_ARCHITECTURE_FALLBACK_OS "${AVM_SYSTEM_ARCHITECTURE_FALLBACK_OS}")

if (NOT DEFINED AVM_SYSTEM_ARCHITECTURE_STRING OR AVM_SYSTEM_ARCHITECTURE_STRING STREQUAL "")
set(AVM_SYSTEM_ARCHITECTURE_STRING
"${AVM_SYSTEM_ARCHITECTURE_FALLBACK_ARCH}-unknown-${AVM_SYSTEM_ARCHITECTURE_FALLBACK_OS}")
endif()

# Add include to directory where avm_version.h is generated so targets linking
# libAtomVM can access it
target_include_directories(libAtomVM PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
Expand Down
6 changes: 2 additions & 4 deletions src/libAtomVM/nifs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3173,13 +3173,11 @@ static term nif_erlang_system_info(Context *ctx, int argc, term argv[])
return term_from_int11(sizeof(avm_float_t));
}
if (key == SYSTEM_ARCHITECTURE_ATOM) {
char buf[128];
snprintf(buf, 128, "%s-%s-%s", SYSTEM_NAME, SYSTEM_VERSION, SYSTEM_ARCHITECTURE);
size_t len = strnlen(buf, 128);
size_t len = sizeof(SYSTEM_ARCHITECTURE_STRING) - 1;
if (memory_ensure_free_opt(ctx, term_binary_heap_size(len), MEMORY_CAN_SHRINK) != MEMORY_GC_OK) {
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
}
return term_from_literal_binary((const uint8_t *) buf, len, &ctx->heap, ctx->global);
return term_from_literal_binary((const uint8_t *) SYSTEM_ARCHITECTURE_STRING, len, &ctx->heap, ctx->global);
}
if (key == ATOMVM_VERSION_ATOM) {
size_t len = strlen(ATOMVM_VERSION);
Expand Down
1 change: 1 addition & 0 deletions src/libAtomVM/version.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@
#define SYSTEM_NAME "${CMAKE_SYSTEM_NAME}"
#define SYSTEM_VERSION "${CMAKE_SYSTEM_VERSION}"
#define SYSTEM_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}"
#define SYSTEM_ARCHITECTURE_STRING "${AVM_SYSTEM_ARCHITECTURE_STRING}"
#define ATOMVM_VERSION "${ATOMVM_VERSION}"
3 changes: 3 additions & 0 deletions src/platforms/emscripten/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ add_executable(AtomVM main.c)

target_compile_features(AtomVM PUBLIC c_std_11)

include(SystemArchitecture)
avm_get_system_architecture_string(AVM_SYSTEM_ARCHITECTURE_STRING)

add_subdirectory(../../../libAtomVM libAtomVM)
target_link_libraries(AtomVM PUBLIC libAtomVM)
target_compile_options(libAtomVM PUBLIC -O3 -fno-exceptions -fno-rtti -pthread -sINLINING_LIMIT -sUSE_ZLIB=1)
Expand Down
3 changes: 3 additions & 0 deletions src/platforms/esp32/components/libatomvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ idf_component_register(INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../../../lib
# "pedantic" flag should be disabled rather poluting diagnostics with warnings caused from 3rd party
option(AVM_PEDANTIC_WARNINGS "Pedantic compiler warnings" OFF)

include(SystemArchitecture)
avm_get_system_architecture_string(AVM_SYSTEM_ARCHITECTURE_STRING PLATFORM_OS esp_idf)

add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../libAtomVM" "libAtomVM")

# Add directory with platform_atomic.h if we mean to use it
Expand Down
2 changes: 2 additions & 0 deletions src/platforms/esp32/test/main/test_erl_sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ compile_erlang(test_rtc_slow)
compile_erlang(test_select)
compile_erlang(test_socket)
compile_erlang(test_ssl)
compile_erlang(test_system_architecture)
compile_erlang(test_time_and_processes)
compile_erlang(test_twdt)
compile_erlang(test_tz)
Expand All @@ -96,6 +97,7 @@ set(erlang_test_beams
test_select.beam
test_socket.beam
test_ssl.beam
test_system_architecture.beam
test_time_and_processes.beam
test_twdt.beam
test_tz.beam
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
%
% This file is part of AtomVM.
%
% Copyright 2026 Peter M. <petermm@gmail.com>
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.
%
% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
%

-module(test_system_architecture).
-export([start/0]).

start() ->
SystemArchitecture = erlang:system_info(system_architecture),
ok =
case SystemArchitecture of
<<"xtensa-esp-esp_idf">> ->
ok;
<<"riscv32-esp-esp_idf">> ->
ok
end,
nomatch = binary:match(SystemArchitecture, <<"esp_idf-">>),
ok.
6 changes: 6 additions & 0 deletions src/platforms/esp32/test/main/test_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,12 @@ TEST_CASE("test_time_and_processes", "[test_run]")
TEST_ASSERT(term_to_int(ret_value) == 6);
}

TEST_CASE("test_system_architecture", "[test_run]")
{
term ret_value = avm_test_case("test_system_architecture.beam");
TEST_ASSERT(ret_value == OK_ATOM);
}

TEST_CASE("test_tz", "[test_run]")
{
term ret_value = avm_test_case("test_tz.beam");
Expand Down
5 changes: 5 additions & 0 deletions src/platforms/generic_unix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ endif()
add_subdirectory(lib)
target_include_directories(AtomVM PUBLIC lib/)

include(SystemArchitecture)
if (NOT DEFINED AVM_SYSTEM_ARCHITECTURE_STRING OR "${AVM_SYSTEM_ARCHITECTURE_STRING}" STREQUAL "")
avm_get_system_architecture_string(AVM_SYSTEM_ARCHITECTURE_STRING)
endif()

add_subdirectory(../../libAtomVM libAtomVM)
target_link_libraries(AtomVM PRIVATE libAtomVM)

Expand Down
2 changes: 2 additions & 0 deletions src/platforms/rp2/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ set(HAVE_PLATFORM_SMP_H ON)
if(PICO_RP2040)
set(HAVE_PLATFORM_ATOMIC_H ON)
endif()
include(SystemArchitecture)
avm_get_system_architecture_string(AVM_SYSTEM_ARCHITECTURE_STRING PLATFORM_VENDOR rp2 PLATFORM_OS none)
add_subdirectory(../../../libAtomVM libAtomVM)
target_link_libraries(AtomVM PUBLIC libAtomVM)
# Also add lib where platform_smp.h and platform_atomic headers are
Expand Down
2 changes: 2 additions & 0 deletions src/platforms/stm32/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ target_include_directories(${PROJECT_EXECUTABLE} PUBLIC
add_dependencies(${PROJECT_EXECUTABLE} picolibc)

# Link libAtomVM
include(SystemArchitecture)
avm_get_system_architecture_string(AVM_SYSTEM_ARCHITECTURE_STRING PLATFORM_VENDOR stm32 PLATFORM_OS none)
add_subdirectory(../../../libAtomVM libAtomVM)
add_dependencies(libAtomVM picolibc)
target_link_libraries(${PROJECT_EXECUTABLE} PUBLIC libAtomVM)
Expand Down
15 changes: 14 additions & 1 deletion tests/erlang_tests/test_system_info.erl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ start() ->
% beam returns a list and probably so should AtomVM.
assert(is_list(erlang:system_info(system_architecture)));
_ ->
assert(is_binary(erlang:system_info(system_architecture)))
SystemArchitecture = erlang:system_info(system_architecture),
assert(is_binary(SystemArchitecture)),
2 = count_hyphens(SystemArchitecture),
false = starts_with_known_os(SystemArchitecture)
end,
SystemVersion = erlang:system_info(system_version),
true = is_list(SystemVersion),
Expand Down Expand Up @@ -74,6 +77,16 @@ loop(Pid) ->

assert(true) -> ok.

count_hyphens(<<>>) -> 0;
count_hyphens(<<"-", Rest/binary>>) -> 1 + count_hyphens(Rest);
count_hyphens(<<_, Rest/binary>>) -> count_hyphens(Rest).

starts_with_known_os(<<"Darwin-", _/binary>>) -> true;
starts_with_known_os(<<"Linux-", _/binary>>) -> true;
starts_with_known_os(<<"FreeBSD-", _/binary>>) -> true;
starts_with_known_os(<<"DragonFly-", _/binary>>) -> true;
starts_with_known_os(_) -> false.

test_port_count("BEAM") ->
N = erlang:system_info(port_count),
true = is_integer(N),
Expand Down
Loading